<?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>Matt Mecham&#039;s Blog &#187; Programming</title>
	<atom:link href="http://blog.mattmecham.com/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.mattmecham.com</link>
	<description>A utopia of randomness from a bloke who develops internet software and is also a dad</description>
	<lastBuildDate>Mon, 12 Dec 2011 16:27:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Why social networking is not the end for forums</title>
		<link>http://blog.mattmecham.com/2009/11/30/why-social-networking-is-not-the-end-for-forums/</link>
		<comments>http://blog.mattmecham.com/2009/11/30/why-social-networking-is-not-the-end-for-forums/#comments</comments>
		<pubDate>Mon, 30 Nov 2009 10:30:18 +0000</pubDate>
		<dc:creator>Matt Mecham</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[IPB]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.mattmecham.com/?p=486</guid>
		<description><![CDATA[I see a lot of questions centred around social networking sites like Twitter and Facebook and how it will affect forums. I also see a lot of people saying that we should focus on social networking for IP.Board to stay competitive. This crops up every few days. It&#8217;s regular enough for me to try and [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>I see a lot of questions centred around social networking sites like Twitter and Facebook and how it will affect forums. I also see a lot of people saying that we should focus on social networking for IP.Board to stay competitive. This crops up every few days. It&#8217;s regular enough for me to try and encapsulate my thoughts in a single easy-to-link-to blog entry.</p>
<p>Before I get into the real meat of the debate, let&#8217;s first take a look at social networking sites like Twitter and Facebook.</p>
<p>You&#8217;d be a fool to ignore the speed at which these sites have grown in popularity. I joined Facebook several years ago before the boom. Back then it was very US-centric and was literally a profile page with a few tools to communicate to other Facebook users. Twitter started life many years ago as &#8220;Twittr&#8221;; a simple service to allow remotely scattered developers working for a single company to keep up-to-date. Both of these sites have grown rapidly and evolved into hugely influential websites boasting trillions of page views and millions of users.</p>
<p>So, it&#8217;s natural to point to these sites and ask &#8220;Why can&#8217;t I have that?&#8221;.</p>
<p>The reason you can&#8217;t replicate Facebook on your own site is that <strong>forums are little islands of content</strong>. Your site is in a great and vast sea with many other islands all competing for the same tourism. Facebook and Twitter is a giant metropolis of users generating user-focused content. These users are well connected with new friends just a short click away.</p>
<p>The humble forum hasn&#8217;t changed much over the past decade. Sure, they look a bit cooler. They have a few more widgets and offer more interactivity but essentially they are the same as when I started hacking up BoardMaster ten long years ago. Back in the dark days of the internet forums were &#8216;bulletin boards&#8217;. Very simple programs in which you &#8220;logged on&#8221; and left a message. This evolved along with &#8220;<a href="http://en.wikipedia.org/wiki/LISTSERV">listserv</a>&#8221; another simple program to consolidate email conversations into a threaded discussion. The only real revolution came when <a href="http://en.wikipedia.org/wiki/Infopop">Infopop</a> (now amusingly named &#8216;Groupee&#8217;) created the flat view board that we&#8217;re all familiar with now.</p>
<p>The first question we should ask is why hasn&#8217;t the core functionality changed?</p>
<p>The answer is quite simple. The way we interact with forums hasn&#8217;t changed. Forums are <strong>content-centric</strong> by nature. This is a very important point to make. Very early bulletin boards cared little for the user apart from their email address or name so that one knew who authored the content. Think about the forums you regularly visit. Do you visit them to catch up with your buddies or do you visit them to join in a themed conversation? To get support on a product you own maybe? Or perhaps to catch up with the gossip after last nights X Factor? Whatever your reason, it&#8217;s almost certainly because of the <strong>content</strong>, not the <em>members</em>. </p>
<p>Forums haven&#8217;t changed because we still need strongly organised and categorised discussion. Facebook may have &#8220;discussion boards&#8221; on its group pages but it is a weak system. There have been a few stabs at changing forum software, but in most cases they are not successful because they miss the point.</p>
<p>I don&#8217;t wish to single out a single application, but <a href="http://vanillaforums.org/discussions">Vanilla</a> springs to mind. At first glance, it&#8217;s a nice clean board with minimal clutter that will surely appeal to many. But could you run a support community with that software? Can you imagine if you had five software products, how would you categorise the conversations? With Vanilla you couldn&#8217;t. And it&#8217;s the same with the Facebook discussion plug-in.</p>
<p>Successful forums have a purpose. I&#8217;ve seen hundreds of &#8220;My Chat Site&#8221; forums appear and vanish as quickly because they offer nothing unique. There are thousands of active forums that focus on a single interest, such as fitness, movies or cars. If these forums continue to market themselves correctly and generate a good deal of unique content each day they will be under no threat from Facebook or Twitter.</p>
<p><em>So, nothing&#8217;s changed in ten years?</em></p>
<p>Not quite. We, at IPS, have made a subtle change in our verbiage. We sell community building software, not forums. This is not just marketing mumbo-jumbo. It underlines that our software has features and tools to build a community. IP.Board is still content-centric but it has greatly expanded the amount of user-centric functionality. We have extended profiles, such as the user-photos, the about-me box, as well as blogs and gallery. These tools add value to your members and give them a <em>secondary</em> reason to come back to your island regularly.</p>
<p><em>So, why can&#8217;t I have a slice of Facebook for my Twilight fan site?</em></p>
<p>Facebook works because it&#8217;s a single site. If Facebook was downloadable software that you had to install then it wouldn&#8217;t work. You would need to create different log ins for each site and update each status update individually. Quite clearly that&#8217;s not going to set the world on fire.<br />
Twitter works because you make a status update and it&#8217;s immediately available to millions of people who can click a button and follow me, or reply to me, or RT my tweet. If you had to copy the tweet to your own Twitter site and paste it, or you had to sign up to my Twitter site to reply, it wouldn&#8217;t work.<br />
You can distill this into a simple statement: Facebook and Twitter is centred squarely on its members talking about <strong>themselves</strong>. A bewildering and expansive array of random subjects.</p>
<p>We, at IP.Board, could easily replicate Facebook&#8217;s tools and indeed we have started to see a few creep in, like status updates. But no matter how many &#8220;social networking&#8221; tools we add, I&#8217;m not going to join a Twilight Fan site just to update my status so I can tell its users about my day. Why would I? A Twilight Fan site is full of Twilight fans talking about Twilight. I have no interest in that, and they surely have no interest in me.</p>
<p>I&#8217;m sure many Twilight fans are interested in PHP coding, but you wouldn&#8217;t add a PHP coding forum to a Twilight fan site and expect it to generate hundreds of new members.</p>
<p><em>But Facebook is killing me and stealing all my users!</em></p>
<p>I don&#8217;t wish to be obtuse, but if Facebook really is stealing your users, then you need to take a good hard look at your forum and its place in the world. If you don&#8217;t have a strong theme or compelling content then your users won&#8217;t have a reason to come back and the few friendships that your users develop on your forum will be moved onto Facebook because Facebook is a much better at developing online friendships.</p>
<p>Take a look at any popular site. How about <a href="http://idolforums.com/">Idol Forums</a>; a forum for American Idol fans. Could you run that 21,000,000 post community from Facebook or Twitter and have it continue to thrive? Of course not.</p>
<p><em>So you&#8217;re saying that IP.Board will eschew social networking as if its some kind of pariah?</em></p>
<p>Not at all. This is the problem with stating your point of view, it&#8217;s instantly assumed that you oppose the other. This is not true. I see value in adding secondary reasons to get your members to come back. Whether that&#8217;s to check their personal conversations, or to write up their blogs, or to add their holiday snaps to their gallery. This is what makes your forum a community.</p>
<p>IP.Board 3 already uses Facebook Connect to allow you to syphon off a good slice of Facebook traffic into your community. Don&#8217;t expect people to join up just to chat. But if you have a unique reason to visit, people will. Especially as you can effectively log right into the board with your Facebook account.</p>
<p>You can use Facebook and Twitter to generate traffic to your site. We have an <a href="http://www.twitter.com/invisionps">official twitter account</a> and an <a href="http://www.facebook.com/pages/Forest-VA/Invision-Power-Services/138687025825">official Facebook page</a>. We use both of these mediums to drive traffic back to our site.</p>
<p>Keep marketing yourself well, compliment your site with social networking, keep your members happy and generating good content and you will continue to thrive.</p>
<p>I&#8217;ll leave you with this final thought, Jerry Springer style: If social networking is an unstoppable juggernaut that will devour the forum format then why have forward thinking companies such as <a href="https://forum.vodafone.ie/">Vodafone</a> and <a href="http://broadcast.oreilly.com/2009/11/announcing-oreilly-answers.html">O&#8217;Reilly</a> just commissioned new communities built with IP.Board?</p>
<div class="addthis_toolbox addthis_default_style " addthis:url='http://blog.mattmecham.com/2009/11/30/why-social-networking-is-not-the-end-for-forums/' addthis:title='Why social networking is not the end for forums '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.mattmecham.com/2009/11/30/why-social-networking-is-not-the-end-for-forums/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Community Content System</title>
		<link>http://blog.mattmecham.com/2009/06/22/community-content-system/</link>
		<comments>http://blog.mattmecham.com/2009/06/22/community-content-system/#comments</comments>
		<pubDate>Mon, 22 Jun 2009 16:46:08 +0000</pubDate>
		<dc:creator>Matt Mecham</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.mattmecham.com/?p=270</guid>
		<description><![CDATA[If you haven&#8217;t already, check out our forthcoming Community Content System: an easy way to add pages to your website. The core of the CCS application centers around allowing you to create pages for your website. The way you create pages and the types of pages you create will be specific to your site, however [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>If you haven&#8217;t already, check out our forthcoming Community Content System: an easy way to add pages to your website.</p>
<blockquote><p>The core of the CCS application centers around allowing you to create pages for your website. The way you create pages and the types of pages you create will be specific to your site, however the process is the same. One administrator may want to build the full front of their website using CCS, while another administrator may want to add some pages within the forums that are not there by default. Both scenarios can be covered by CCS.</p></blockquote>
<p>More information available <a href="http://forums.invisionpower.com/blog/1174/entry-3420-ccs-pages-overview/">here</a>. Check out the video to your right. Those dulcet tones belong to Charles.</p>
<div class="addthis_toolbox addthis_default_style " addthis:url='http://blog.mattmecham.com/2009/06/22/community-content-system/' addthis:title='Community Content System '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.mattmecham.com/2009/06/22/community-content-system/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The final debate</title>
		<link>http://blog.mattmecham.com/2009/06/19/the-final-debate/</link>
		<comments>http://blog.mattmecham.com/2009/06/19/the-final-debate/#comments</comments>
		<pubDate>Fri, 19 Jun 2009 15:58:09 +0000</pubDate>
		<dc:creator>Matt Mecham</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.mattmecham.com/?p=261</guid>
		<description><![CDATA[I could be forgiven for getting a sense of deja-vu at the forthcoming &#8216;final&#8217; release of IP.Board 3.0.0. It&#8217;s a few months short of ten years since I released an alpha of Ikonboard and since then I&#8217;ve been in this position many times. A &#8216;final&#8217; release of a new major version is an oxymoron. IP.Board [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>I could be forgiven for getting a sense of deja-vu at the forthcoming &#8216;final&#8217; release of IP.Board 3.0.0. It&#8217;s a few months short of ten years since I released an alpha of Ikonboard and since then I&#8217;ve been in this position many times.</p>
<p><strong>A &#8216;final&#8217; release of a new major version is an oxymoron.</strong><br />
IP.Board 3.0.0 is no exception. The trouble is that this is not immediately obvious to many people. A fair number of people see a &#8216;final&#8217; (sometimes called &#8216;gold&#8217; in other circles) as a stamp of assuredness and completeness; a final product without any concessions such as bugs.</p>
<p>IP.Board 3 is a dramatic change change from the 2.3 codebase. This truly is a major upgrade. So much has changed, there&#8217;s virtually not a line of code left intact from 2.3.6. The core framework has changed for the better so much that is almost unrecognizable from IP.Board 2.</p>
<p>That gives us a lot of untested code in a lot of untested scenarios. We have undertaken a very long period of beta testing. Far longer than we had anticipated but we feel that the end justifies the means. We have a very stable product that only has relatively minor issues. Not including a hasty fix made to the bulk mailer 20 minutes before we released RC 2. That aside, the bugs we&#8217;ve fixed are mostly trivial (language missing, quirky browser bugs, etc) or esoteric (character set encoding issues, safe mode issues, etc).</p>
<p>However, no amount of beta testing will truly free a product of bugs. Especially one so comprehensively new as IP.Board 3.0.0. This is where the confusion is born. It is inevitable that &#8216;final&#8217; will still contain some issues. They will be relatively minor and impact few but they will still be there. This shouldn&#8217;t surprise as this is the first release of our new software but it does catch a few people out. Both the 1.x and 2.x branches took several releases before the bug reporting rate slowed up.</p>
<p>Of course, I don&#8217;t want to put you off upgrading; quite the contrary. We&#8217;re using 3.0.0 RC 2 on our<a href="http://forums.invisionpower.com"> company forums</a> just fine and we experience barely any issues and you should expect the same.</p>
<p>Keep in mind that when 3.0.0 has been released we plan to make small frequent minor releases to address any pertinent issues. This may be bothersome for some, but it really is the best way of deploying fixes quickly.</p>
<p>Whatever you chose, we hope that you enjoy using 3.0.0. It&#8217;s been a long journey and we thank you for sharing it with us.</p>
<div class="addthis_toolbox addthis_default_style " addthis:url='http://blog.mattmecham.com/2009/06/19/the-final-debate/' addthis:title='The final debate '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.mattmecham.com/2009/06/19/the-final-debate/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>PHP 5 Will Make You A Better PHP Programmer</title>
		<link>http://blog.mattmecham.com/2008/10/03/php-5-will-make-you-a-better-php-programmer/</link>
		<comments>http://blog.mattmecham.com/2008/10/03/php-5-will-make-you-a-better-php-programmer/#comments</comments>
		<pubDate>Fri, 03 Oct 2008 11:37:26 +0000</pubDate>
		<dc:creator>Matt Mecham</dc:creator>
				<category><![CDATA[IPB]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.mattmecham.com/?p=221</guid>
		<description><![CDATA[My apologies for the overly verbose title of this blog entry. But it&#8217;s true. Embracing PHP 5 will make you a better programmer. At least, it has for me. This minor epiphany revealed itself during yesterday&#8217;s Captcha Crisis over at IPS HeadQuarters. In a nut shell, some naughty spammer defeated our CAPTCHA and registered thousands [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>My apologies for the overly verbose title of this blog entry. But it&#8217;s true. Embracing PHP 5 will make you a better programmer. At least, it has for me.</p>
<p>This minor epiphany revealed itself during yesterday&#8217;s <a href="http://forums.invisionpower.com/index.php?showtopic=277487">Captcha Crisis</a> over at IPS HeadQuarters. In a nut shell, some naughty spammer defeated our CAPTCHA and registered thousands of member accounts across hundreds of IP.Boards.</p>
<p>We had to react fast and <a href="http://forums.invisionpower.com/index.php?showtopic=277604&#038;view=getnewpost">release an update</a> that not only fixes our CAPTCHA but also integrated <a href="http://www.recaptcha.net">reCAPTCHA</a> which Brandon had already done for IP.Board 3.0.0.</p>
<p>Now, I&#8217;ve had my head stuck in IP.Board 3.0.0 since February. We made the decision to use PHP 5 so that we can take advantage of all the new &#8220;stuff&#8221; such as improved XML handling, public/private/protected methods and properties and magic methods to name a few. I started from scratch and wrote a brand new framework from the ground up using several PHP 5 tricks along the way. In short, it&#8217;s the classic MCV pattern using static utility classes and a singleton registery. I&#8217;ve blogged about it <a href="http://forums.invisionpower.com/blog/ips_news/index.php?showentry=2536">here</a> although that&#8217;s a touch out-of-date but still fairly representative of the new framework.</p>
<p>So. With many customers asking us for a fix, the pressure was on. Josh, Brandon and I down-tooled and went to work on IP.Board 2.3.6. And what a minor shock that was! After nearly 8 months of using the new framework, it seemed backward to use $this->ipsclass for everything. Worse, I was limited to using PHP 4. Worse still was that all the captcha calls were de-centralized. Ouch.</p>
<p>Captcha code was copied through many files. This is a natural progression for stable code that gets developed over time. You start off with the captcha in one place. You then want to add it elsewhere, so you copy the code and paste it in place. Rinse and repeat. You do this because there is a real fear of changing too much code for minor releases. Even though you know it&#8217;s bad.</p>
<p>I decided to write a micro-framework to handle all captcha challenges; to centralize it into one public facing class which calls on little plug-in classes which provide the functionality. Performing this routine task is when it I discovered just how much better PHP 5 is.</p>
<p>Without the ability to set methods and properties to private, the code seemed harder to departmentalize. Without magic methods to offload method requests, I had to make do with pointless functions to do the same. Without the ability to chain functions together, I had to fudge something that does the same job. Any desire to write nice and tight code goes out of the window with PHP 4. It doesn&#8217;t try very hard to do things properly, so you don&#8217;t.</p>
<p>Once the mini-framework was complete, I set about updating IP.Board 3.0.0 to use the same methods. Thankfully, we had already decentralized CAPTCHA creation to a single class. The ability to drop in new plugins and have new CAPTCHA methods seemed useful, so I re-wrote the framework for PHP 5 and it was much more pleasurable experience!</p>
<p>To compare, here&#8217;s the mini-framework in PHP 4:</p>
<pre><code>/**
	* Constructor bah to PHP 4
	*
	* @param	object		IPSClass object
	* @param	string		Captcha plug-in to use
	*/
	function class_captcha( $ipsclass, $plugin )
	{
		$this->ipsclass =&#038; $ipsclass;
		$plugin         = $this->ipsclass->txt_alphanumerical_clean( $plugin );</code>
		<code>
		if ( ! file_exists( KERNEL_PATH . 'class_captcha_plugin/' . $plugin . '.php' ) )
		{
			$plugin = 'default';
		}
		</code><code>
		require_once( KERNEL_PATH . 'class_captcha_plugin/' . $plugin . '.php' );
		$this->_plugInClass = new captchaPlugIn( $ipsclass );
	}
	</code><code>
	/**
	* Returns template bit
	*
	* @return string	HTML Template bit
	*/
	function getTemplate()
	{
		return $this->_plugInClass->getTemplate();
	}
</code><code>
	/**
	* Validate challenge
	*
	* @return	boolean
	* @since	1.0
	*/

	function validate()
	{
		return $this->_plugInClass->validate();
	}
</code><code>
	/**
	* Fetch Plug In Class Handle
	*
	* If you need it...
	*/
	function fetchPlugInClassHandle()
	{
		return $this->_plugInClass;
	}</code></pre>
<p>And here&#8217;s the same functionality, but in PHP 5:</p>
<pre><code>/**
	* Constructor
	*/
	function __construct( ipsRegistry $registry )
	{
		$this->registry = $registry;
		$this->DB       = $this->registry->DB();
		$this->settings = $this->registry->settings();
		$this->request  = $this->registry->request();
		$this->lang     = $this->registry->getClass('class_localization');
		$this->member   = $this->registry->member();
		</code><code>
		$plugin = $this->settings['bot_antispam_type'];
		</code><code>
		if ( ! file_exists( IPS_KERNEL_PATH . 'classCaptchaPlugin/' . $plugin . '.php' ) )
		{
			$plugin = 'default';
		}
	</code><code>
		require_once( IPS_KERNEL_PATH . 'classCaptchaPlugin/' . $plugin . '.php' );
		$this->_plugInClass = new captchaPlugIn( $registry );
	}
	</code><code>
	/**
	* Magic Call method
	*
	* @param	string	Method Name
	* @param	mixed	Method arguments
	* @return   mixed
	*/
	public function __call( $method, $arguments )
	{
		if ( method_exists( $this->_plugInClass, $method ) )
		{
			return $this->_plugInClass->$method( $arguments );
		}
		else
		{
			trigger_error( $method . " does not exist", E_USER_ERROR );
		}
	}
	</code><code>
	/**
	* Magic __get method
	*
	* @access	public
	* @param	mixed
	* @return	mixed
	*/
	public function __get( $name )
	{
		if ( property_exists( $this->_plugInClass, $name ) )
		{
			return $this->_plugInClass->$name;
		}
		else
		{
			trigger_error( $name . " does not exist", E_USER_ERROR );
		}
	}</code></pre>
<p>Now, isn&#8217;t that much nicer!</p>
<p>Take advantage of all PHP 5 offers and your code will improve. Just looking at the difference between IP.Board 2.3&#8242;s and IP.Board 3.0.0 proves that PHP 5 has helped me become a much better programmer.</p>
<div class="addthis_toolbox addthis_default_style " addthis:url='http://blog.mattmecham.com/2008/10/03/php-5-will-make-you-a-better-php-programmer/' addthis:title='PHP 5 Will Make You A Better PHP Programmer '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.mattmecham.com/2008/10/03/php-5-will-make-you-a-better-php-programmer/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>IP.Nexus, revealed</title>
		<link>http://blog.mattmecham.com/2007/09/17/ipnexus-revealed/</link>
		<comments>http://blog.mattmecham.com/2007/09/17/ipnexus-revealed/#comments</comments>
		<pubDate>Mon, 17 Sep 2007 15:28:21 +0000</pubDate>
		<dc:creator>Matt Mecham</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.mattmecham.com/2007/09/17/ipnexus-revealed/</guid>
		<description><![CDATA[.. and the wait is over! If you&#8217;ve not already seen this, go see it now!]]></description>
			<content:encoded><![CDATA[<p></p><p>.. and the wait is over!</p>
<p>If you&#8217;ve not already <a href="http://forums.invisionpower.com/index.php?showtopic=237153">seen this</a>, go see it now!</p>
<div class="addthis_toolbox addthis_default_style " addthis:url='http://blog.mattmecham.com/2007/09/17/ipnexus-revealed/' addthis:title='IP.Nexus, revealed '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.mattmecham.com/2007/09/17/ipnexus-revealed/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Seriously Sucky Safari</title>
		<link>http://blog.mattmecham.com/2007/06/12/seriously-sucky-safari/</link>
		<comments>http://blog.mattmecham.com/2007/06/12/seriously-sucky-safari/#comments</comments>
		<pubDate>Tue, 12 Jun 2007 14:18:59 +0000</pubDate>
		<dc:creator>Matt Mecham</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.mattmecham.com/2007/06/12/seriously-sucky-safari/</guid>
		<description><![CDATA[<a href="http://blog.mattmecham.com/2007/06/12/seriously-sucky-safari/"><img align="left" hspace="5" width="75" src="http://blog.mattmecham.com/blogimagesmonthly/07-06/safari.gif" class="alignleft wp-post-image tfe" alt="" title="" /></a>I spent the greater half of last week tearing out clumps of hair in sheer frustration over an annoying bug in Safari. It wasn&#8217;t the kind of bug that you could really code around. I can&#8217;t get into specifics but it was to do with iFrames and javascript. The bug caused a significant problem with [...]]]></description>
			<content:encoded><![CDATA[<p></p><p style="float: right"><img src="http://blog.mattmecham.com/blogimagesmonthly/07-06/safari.gif" border="0" /></p>
<p>I spent the greater half of last week tearing out clumps of hair in sheer frustration over an annoying bug in Safari.</p>
<p>It wasn&#8217;t the kind of bug that you could really code around. I can&#8217;t get into specifics but it was to do with iFrames and javascript. The bug caused a significant problem with how the application I&#8217;m working on functions.</p>
<p>This was the beginning of four days of javascript hell.  The end result of which is a lot of recoding and a fair amount of patching to get it sort of working. A search on the &#8216;net revealed that it was a known bug in Apple&#8217;s WebKit which has been fixed already in the next version which isn&#8217;t due out until the next version of OS X ships.</p>
<p>It transpires that this abomination of a web browser is now being <a href="http://www.apple.com/safari/">inflicted on Windows</a> users now. I can&#8217;t wait to see which bugs show up in Windows that don&#8217;t show up in OS X.</p>
<p>I love Apple. I really do. But Safari is a constant thorn in my side and I wish it would go away. I&#8217;d love for Apple to stop dicking around with their WebKit and use Gecko instead.</p>
<p>What finished me off is that I&#8217;ve had zero problems with IE 7 and my javascript code.</p>
<p>Safari: The Web&#8217;s Best Browser? I&#8217;ll allow my SVN commit messages tell you what I think:</p>
<p><img src="http://blog.mattmecham.com/blogimagesmonthly/07-06/ihatesafariandithatesme.gif" /></p>
<div class="addthis_toolbox addthis_default_style " addthis:url='http://blog.mattmecham.com/2007/06/12/seriously-sucky-safari/' addthis:title='Seriously Sucky Safari '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.mattmecham.com/2007/06/12/seriously-sucky-safari/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>HTTP Only cookies in Firefox</title>
		<link>http://blog.mattmecham.com/2006/09/14/http-only-cookies-in-firefox/</link>
		<comments>http://blog.mattmecham.com/2006/09/14/http-only-cookies-in-firefox/#comments</comments>
		<pubDate>Thu, 14 Sep 2006 17:28:15 +0000</pubDate>
		<dc:creator>Matt Mecham</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.mattmecham.com/blog1/2006/09/14/http-only-cookies-in-firefox/</guid>
		<description><![CDATA[This follows up from my previous entry where I found a very easy way to set HttpOnly cookies for Internet Explorer 6 (SP1+) without requiring PHP 5.2 or hand-rolling set-cookie routines. Due to reasons too long to explain here Firefox doesn&#8217;t have support for these cookies yet. However, there is a Firefox (well, Gecko) only [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>This follows up from my <a href="http://blog.mattmecham.com/2006/09/12/http-only-cookies-without-php-52/">previous entry</a> where I found a very easy way to set <a href="http://msdn.microsoft.com/workshop/author/dhtml/httponly_cookies.asp">HttpOnly cookies</a> for Internet Explorer 6 (SP1+) without requiring PHP 5.2 or hand-rolling set-cookie routines.</p>
<p>Due to reasons <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=178993">too long to explain here</a> Firefox doesn&#8217;t have support for these cookies yet. However, there is a Firefox (well, Gecko) only <a href="http://www.wisec.it/sectou.php?id=44c7949f6de03&amp;lang=en">solution.</a></p>
<p>The solution requires you to add this simple line of javascript as near to the top of your document as you can.</p>
<p><kbd>HTMLDocument.prototype.__defineGetter__("cookie",function (){return null;});</kbd></p>
<p>This overwrites the default cookie &#8220;getter&#8221; function and simply returns &#8220;null&#8221; when document.cookie is requested.</p>
<p>Unfortunately, it suffers from two major problems.</p>
<p>Firstly, it prevents <em>any</em> cookies from being read by javascript. This is a problem if you have javascript set and get cookies on the fly for dynamic web applications (read Web 2.0). and more fatally it can be undone simply by using:</p>
<p><kbd>delete HTMLDocument.prototype.cookie</kbd>.</p>
<p>For example, if you managed to craft a link like so:</p>
<p><kbd>&lt;a href='javascript:alert(document.cookie)'&gt;Click me!&lt;/a&gt;</kbd></p>
<p>Then you&#8217;d get an alert box with &#8220;null&#8221; thanks to the overridden cookie getter &#8211; however, crafting this link:</p>
<p><kbd>&lt;a href='javascript:delete HTMLDocument.prototype.cookie; alert(document.cookie)'&gt;Click me!&lt;/a&gt;</kbd></p>
<p>Then you&#8217;d get access to the document.cookie as we&#8217;ve just deleted our custom getter.</p>
<p>The first problem is quite easy to overcome. You can set up an array of cookies that you want to &#8216;hide&#8217; then parse up document.cookie storing the cookie values into an array and simply return the value of the array key when you would otherwise request a cookie.</p>
<p>The second problem is a little more difficult. After toying with it for a little while, I took a rather crude approach. I simply add an onload function that examines the document&#8217;s innerHTML and just replace &#8220;HTMLDocument.prototype&#8221; with a safer version (note, you can&#8217;t convert to hex or ascii entities as Firefox runs it just the same). There are two cavaets however.</p>
<p>Firstly, this will only stop &#8220;passive&#8221; attacks &#8211; that is scripting in URLs and images. It won&#8217;t stop a &lt;script&gt;..&amp;lt/script&gt; block of code as the script code is executed before the onload function is called. Secondly, as the document&#8217;s innerHTML is replaced, all subsequent javascript on the page will stop working. I don&#8217;t consider that a major stumbling block as there aren&#8217;t many legitimate cases where you&#8217;d want someone to post &#8220;HTMLDocument.prototype&#8221;. If it is a problem, then I suggest you add a line of code in your PHP script to convert this string into something safer before javascript has a chance to see it.</p>
<p>Of course, this isn&#8217;t an excuse to stop checking for javascript in URLs and images &#8211; but it does provide another barrier a determined hacker must overcome before accessing your cookie information. It&#8217;s also not fool proof. There are hundreds of ways to obfuscate javascript code and it&#8217;s almost impossible to catch them all. Hopefully when Firefox 2 is out of BETA it&#8217;ll support HttpOnly cookies and deprecate this rather crude solution.</p>
<p>Here&#8217;s the complete code.</p>
<div style="font-size: 10px; font-family: Courier, 'Courier New'; monaco;white-space: pre;">var ignore_cookies = new Array( &#8216;session_id&#8217;, &#8216;password&#8217;, &#8216;member_id&#8217; );<br />
var COOKIES = new Array();<br />
var uagent = navigator.userAgent.toLowerCase();<br />
var is_moz = ( navigator.product == &#8216;Gecko&#8217; );<br />
var _tmp = document.cookie.split(&#8216;;&#8217;);if ( _tmp.length )<br />
{<br />
for( i = 0 ; i &lt; _tmp.length ; i++ )<br />
{<br />
var _data = _tmp[i].split(&#8216;=&#8217;);<br />
var _key = php_trim( _data[0] );<br />
var _value = unescape( php_trim( _data[1] ) );</p>
<p>if ( _key &amp;&amp; ( ! php_in_array( _key, ignore_cookies ) ) )<br />
{<br />
COOKIES[ _key ] = _value;<br />
}<br />
}<br />
}</p>
<p>_tmp = null;</p>
<p>if ( is_moz )<br />
{<br />
HTMLDocument.prototype.__defineGetter__( &#8220;cookie&#8221;, function () { return null; } );</p>
<p>window.addEventListener( &#8216;load&#8217;, function() {<br />
var _a = document.body;<br />
var _x = _a.innerHTML;<br />
var _y = new RegExp( &#8220;HTMLDocument\.prototype&#8221;, &#8216;ig&#8217; );</p>
<p>if ( _x.match( _y ) )<br />
{<br />
_x = _x.replace( _y, &#8216;HTMLDocument_prototype&#8217; );<br />
_a.innerHTML = _x;<br />
}<br />
}, false );<br />
}</p>
<p>/**<br />
* Emulate PHPs trim function<br />
*/<br />
function php_trim( text )<br />
{<br />
text = text.replace(/^\s+/, &#8221;);<br />
return text.replace(/\s+$/, &#8221;);<br />
};</p>
<p>/**<br />
* Emulate PHPs in_array function<br />
*/<br />
function php_in_array( needle, haystack )<br />
{<br />
if ( ! haystack.length )<br />
{<br />
return false;<br />
}</p>
<p>for ( var i = 0 ; i &lt; haystack.length ; i++)<br />
{<br />
if ( haystack[i] === needle )<br />
{<br />
return true;<br />
}<br />
}</p>
<p>return false;<br />
};</p>
<p>function get_cookie( name )<br />
{<br />
return COOKIES[ name ];<br />
}</p>
</div>
<div class="addthis_toolbox addthis_default_style " addthis:url='http://blog.mattmecham.com/2006/09/14/http-only-cookies-in-firefox/' addthis:title='HTTP Only cookies in Firefox '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.mattmecham.com/2006/09/14/http-only-cookies-in-firefox/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Regular Javascript Expressions</title>
		<link>http://blog.mattmecham.com/2006/08/03/regular-javascript-expressions/</link>
		<comments>http://blog.mattmecham.com/2006/08/03/regular-javascript-expressions/#comments</comments>
		<pubDate>Thu, 03 Aug 2006 16:52:28 +0000</pubDate>
		<dc:creator>Matt Mecham</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.mattmecham.com/blog1/2006/08/03/regular-javascript-expressions/</guid>
		<description><![CDATA[So I had a fun hour this morning. If you&#8217;re unaware, any javascript that&#8217;s returned via ajax (XMLHttpRequest) which is embedded in the returned text isn&#8217;t executed which is a bit of a problem. To &#8216;fix&#8217; this, I wrote a little function in the ajax class that takes the returned text, finds any javascript blocks [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>So I had a fun hour this morning.</p>
<p>If you&#8217;re unaware, any javascript that&#8217;s returned via ajax (XMLHttpRequest) which is embedded in the returned text isn&#8217;t executed which is a bit of a problem.</p>
<p>To &#8216;fix&#8217; this, I wrote a little function in the ajax class that takes the returned text, finds any javascript blocks and eval()s them. The problem is the regex. My first instinct was to write this:</p>
<p>source_code.match( new RegExp( &#8220;&lt;script\s+?type=['"]text/javascript['"]&gt;(.+?)&lt;/script&gt;&#8221;, &#8220;i&#8221; ) )</p>
<p>However that didn&#8217;t work. After some tweaking it seemed that ( .+?) wasn&#8217;t matching across newlines. A quick search on the internet informed that RegExp&#8217;s dot character doesn&#8217;t match across newlines and I should use ([^]+?) instead ([^] being match every character except (none)).</p>
<p>I made the changes and everything snapped into place, so I figured I&#8217;d quickly blog about it so that I won&#8217;t forget in the future.</p>
<div class="addthis_toolbox addthis_default_style " addthis:url='http://blog.mattmecham.com/2006/08/03/regular-javascript-expressions/' addthis:title='Regular Javascript Expressions '  ><a class="addthis_button_facebook_like" fb:like:layout="button_count"></a><a class="addthis_button_tweet"></a><a class="addthis_counter addthis_pill_style"></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.mattmecham.com/2006/08/03/regular-javascript-expressions/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
	</channel>
</rss>

