<?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>dotvoid.com &#187; Javascript</title>
	<atom:link href="http://www.dotvoid.com/tag/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.dotvoid.com</link>
	<description>Experiments and thoughts in PHP and javascript</description>
	<lastBuildDate>Wed, 08 Sep 2010 06:36:10 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Dynamically change z-index on Google Maps markers</title>
		<link>http://www.dotvoid.com/2010/02/dymaically-change-z-index-on-google-maps-markers/</link>
		<comments>http://www.dotvoid.com/2010/02/dymaically-change-z-index-on-google-maps-markers/#comments</comments>
		<pubDate>Thu, 04 Feb 2010 15:12:00 +0000</pubDate>
		<dc:creator>Danne</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[google maps]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://www.dotvoid.com/?p=440</guid>
		<description><![CDATA[As many have noticed Google Maps API does not include a setIndex() method on the marker. You can set the z-index when adding a marker to the map. But it is not possible to change this afterwards.
I didn&#8217;t find a good solution to the problem when searching and had to resort to my own, hacking [...]]]></description>
			<content:encoded><![CDATA[<p>As many have noticed Google Maps API does not include a setIndex() method on the marker. You can set the z-index <em>when adding a marker</em> to the map. But it is not possible to change this afterwards.</p>
<p>I didn&#8217;t find a good solution to the problem when searching and had to resort to my own, hacking away on Google Maps. As I was feeling really good about myself when I had it working really well I just remembered that <a href="http://code.google.com/apis/maps/documentation/v3/">Google Maps Javascript API V3</a> has been released in Google Labs&#8230; And of course there it was. <a href="http://code.google.com/apis/maps/documentation/v3/reference.html#Marker">The Marker class</a> has a new method, <strong><code>setZIndex(<span class="type">zIndex:number</span>)</code></strong>.</p>
<p>Well, version 3 of the API is still only released by Google Labs which is &#8220;<em>home to developer products that are still in their formative stages</em>&#8220;. So for anyone not inclined to use version 3 just yet, I&#8217;ll write down how I did it here.</p>
<p>As I use JQuery in this particular project the example is also using JQuery. If used in production I suggest using try/catch wherever appropriate as the solution depends on a specific dom structure.</p>
<p>I have the below HTML which is the container for the Google map.</p>
<pre id="line197">&lt;<span class="start-tag">div</span><span class="attribute-name"> id</span>=<span class="attribute-value">"indexmap"</span>&gt;&lt;/<span class="end-tag">div</span>&gt;</pre>
<p>The map is created as below (you&#8217;ll have to add the lat/lng variable values yourselves.</p>
<pre id="line197">var map = new GMap2($('#indexamp'));
var point = new GLatLng(lat, lng);
map.setCenter(point, zoom);</pre>
<p>This, as most know, creates the actual map. Then it is time to add the markers. In my case I have a list of locations with the latitude/longitude in the actual html. JQuery helps me loop over these locations and dynamically add markers in the correct spots. This HTML looks like below. Note how each definition list have an id no with &#8220;mm_&#8221; as prefix. (Never mind any objections you have on having many definition lists like this&#8230; Never mind that these coordinates are fiction&#8230;)</p>
<pre>&lt;dl id="mm_0"&gt;
  &lt;dt&gt;...&lt;/dt&gt;
  &lt;dd&gt;
    &lt;span class="lat"&gt;61.333&lt;/span&gt;&lt;span class="lng"&gt;31.1324&lt;/span&gt;
    Random text
  &lt;/dd&gt;
&lt;/dl&gt;
&lt;dl id="mm_1"&gt;
  &lt;dt&gt;...&lt;/dt&gt;
  &lt;dd&gt;
    &lt;span class="lat"&gt;61.333&lt;/span&gt;&lt;span class="lng"&gt;31.1324&lt;/span&gt;
    Random text
  &lt;/dd&gt;
&lt;/dl&gt;</pre>
<p>What I want is the markers to be highlighted with a different icon every time I hover over a definition list element (dl). However, both have the same coordinates and one of the markers will be hidden behind the other.</p>
<p>So to prepare we need to make sure the actual images in the Google generated map can be connected to these defintion list id:s. The Google map have many different layers on top of each other. One layer contain the foreground images, another the shadows, mouse map definitions and so on. Each of these layers (normal div elements) have their own z-index.</p>
<p>In these different layers the images used have their own z-index. However, the z-index for the marker foreground image is the same as for the transparent clickable marker image. This makes it possible to use the transparent image z-index to restore the foreground image z-index. This is important as not to confuse the user when he later click on a marker&#8230;</p>
<p>So let&#8217;s loop over these images and give them appropriate id values as well as put the markers on the map. (No &#8211; Google does not give them id&#8217;s). This is, stripped to the bare essentials, the complete code with some comments.</p>
<pre id="line197">// Create the map
var map = new GMap2($('#indexamp'));
var point = new GLatLng(lat, lng);
map.setCenter(point, zoom);

// Loop over the definition lists picking up coordinates
var n = 0;
$('dl').each(function() {
	var lat = parseFloat($('span.lat', this).text());
	var lng = parseFloat($('span.lng', this).text());
	var point = new GLatLng(lat, lng);

	// Create the marker with custom images
	var markerIcon = new GIcon(G_DEFAULT_ICON);
	markerIcon.image = 'marker_default.png';
	markerIcon.iconSize = new GSize(23, 30);
	markerIcon.shadow = "marker_shadow.png";
	markerIcon.shadowSize = new GSize(50, 30);
	markerIcon.iconAnchor = new GPoint(11, 29);
	markerIcon.infoWindowAnchor = new GPoint(11, 14);

	var marker = new GMarker(point, {icon: markerIcon});

	// Change the foreground image when hovering over a definition list
	// Note that the actual id's have not been created yet.
	var no = this.id.substring(3); // Exclude the prefix
	$(this).hover(
		function() {
			marker.setImage('marker_selected.png');
			// Bring this image to foreground
			$('#mf_' + no)[0].style.zIndex = 1;
		},
		function() {
			marker.setImage('marker_default.png');
			// Reset the z-index based on the transparent image
			// that has the same z-index
			$('#mf_' + no)[0].style.zIndex = $('#mt_' + no)[0].style.zIndex;
		}
	);
}

// Add id values to the foreground images, based on the
// dom structure created beneath the #indexmap div element used
// as the place holder for the map
n = 0;
$('#indexmap div &gt; div &gt; div:eq(6) img').each(function() {
	this.id = 'mf_' + n++;
});

// Add id values to the shadow images the same way
n = 0;
$('#indexmap div &gt; div &gt; div:eq(8) img').each(function() {
	this.id = 'mt_' + n++;
});</pre>
<p>You might have to amend the code to get it working for you as I have cut&#8217;n pasted different parts. In the real code there is a lot of other things going on that would&#8217;ve made the example above hard to read. I do think however that you should be able to understand how it works.</p>


<div class="shr-bookmarks shr-bookmarks-expand shr-bookmarks-center shr-bookmarks-bg-knowledge">
<ul class="socials">
		<li class="shr-comfeed">
			<a href="http://www.dotvoid.com/2010/02/dymaically-change-z-index-on-google-maps-markers/feed" rel="nofollow" class="external" title="Subscribe to the comments for this post?">Subscribe to the comments for this post?</a>
		</li>
		<li class="shr-delicious">
			<a href="http://delicious.com/post?url=http://www.dotvoid.com/2010/02/dymaically-change-z-index-on-google-maps-markers/&amp;title=Dynamically+change+z-index+on+Google+Maps+markers" rel="nofollow" class="external" title="Share this on del.icio.us">Share this on del.icio.us</a>
		</li>
		<li class="shr-facebook">
			<a href="http://www.facebook.com/share.php?v=4&amp;src=bm&amp;u=http://www.dotvoid.com/2010/02/dymaically-change-z-index-on-google-maps-markers/&amp;t=Dynamically+change+z-index+on+Google+Maps+markers" rel="nofollow" class="external" title="Share this on Facebook">Share this on Facebook</a>
		</li>
		<li class="shr-googlebuzz">
			<a href="http://www.google.com/buzz/post?url=http://www.dotvoid.com/2010/02/dymaically-change-z-index-on-google-maps-markers/&amp;imageurl=" rel="nofollow" class="external" title="Post on Google Buzz">Post on Google Buzz</a>
		</li>
		<li class="shr-linkedin">
			<a href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http://www.dotvoid.com/2010/02/dymaically-change-z-index-on-google-maps-markers/&amp;title=Dynamically+change+z-index+on+Google+Maps+markers&amp;summary=As%20many%20have%20noticed%20Google%20Maps%20API%20does%20not%20include%20a%20setIndex%28%29%20method%20on%20the%20marker.%20You%20can%20set%20the%20z-index%20when%20adding%20a%20marker%20to%20the%20map.%20But%20it%20is%20not%20possible%20to%20change%20this%20afterwards.%0D%0A%0D%0AI%20didn%27t%20find%20a%20good%20solution%20to%20the%20problem%20when%20searching%20and%20had%20to%20resort%20to%20my%20own%2C%20hacking%20away&amp;source=dotvoid.com" rel="nofollow" class="external" title="Share this on LinkedIn">Share this on LinkedIn</a>
		</li>
		<li class="shr-plaxo">
			<a href="http://www.plaxo.com/?share_link=http://www.dotvoid.com/2010/02/dymaically-change-z-index-on-google-maps-markers/" rel="nofollow" class="external" title="Share this on Plaxo">Share this on Plaxo</a>
		</li>
		<li class="shr-stumbleupon">
			<a href="http://www.stumbleupon.com/submit?url=http://www.dotvoid.com/2010/02/dymaically-change-z-index-on-google-maps-markers/&amp;title=Dynamically+change+z-index+on+Google+Maps+markers" rel="nofollow" class="external" title="Stumble upon something good? Share it on StumbleUpon">Stumble upon something good? Share it on StumbleUpon</a>
		</li>
		<li class="shr-twitter">
			<a href="http://twitter.com/home?status=Dynamically+change+z-index+on+Google+Maps+markers+-+http://b2l.me/fjfa4&amp;source=shareaholic" rel="nofollow" class="external" title="Tweet This!">Tweet This!</a>
		</li>
</ul>
<div style="clear:both;"></div>
</div>

]]></content:encoded>
			<wfw:commentRss>http://www.dotvoid.com/2010/02/dymaically-change-z-index-on-google-maps-markers/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Site architecture based on Zend Framework</title>
		<link>http://www.dotvoid.com/2009/10/site-architecture-based-on-zend-framework/</link>
		<comments>http://www.dotvoid.com/2009/10/site-architecture-based-on-zend-framework/#comments</comments>
		<pubDate>Fri, 09 Oct 2009 11:48:54 +0000</pubDate>
		<dc:creator>Danne</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[zend framework]]></category>

		<guid isPermaLink="false">http://www.dotvoid.com/?p=394</guid>
		<description><![CDATA[After working on the Swedish weather site klart.se for awhile I now work on my own projects again. So I have switched Codeigniter to Zend Framework again.
After a trip to Dublin I finally launched the beginning of a new social tourist Dublin guide. It is exactly the same site as both the Swedish Fuengirola guide [...]]]></description>
			<content:encoded><![CDATA[<p>After working on the Swedish weather site klart.se for awhile I now work on my own projects again. So I have switched Codeigniter to <a href="http://framework.zend.com">Zend Framework</a> again.</p>
<p>After a trip to Dublin I finally launched the beginning of a new <a href="http://www.dublincitymap.com/">social tourist Dublin guide</a>. It is exactly the same site as both the <a href="http://www.fuengirolaguide.com">Swedish Fuengirola guide</a> as well as the <a href="http://www.fuengirolamap.com">English Fuengirola guide</a> I launched after living there for five months. The functionality is somewhat basic as of yet but every now and then I&#8217;ll add something more.</p>
<p>Basing three different sites, even though they are very similar, using two different languages gives me the possibility to try out several parts of Zend Framework. It also requires a good design both in the backend and frontend to keep it maintainable. I thought maybe some people would be interested in a basic overview of the different parts needed to put everything together.</p>
<h2>Backend</h2>
<p>The sites aren&#8217;t really that complicated. On a basic level there is a MySQL database and a database layer using Zend_Db/Zend_Db_Table, there is a Zend Framework MVC architecture using models, controllers, views, layouts with Zend_Layout as well as a few view helpers and some HTML, CSS as well as Javascript. All commonly needed. There is more needed to make it a sitethough.</p>
<p>I want as little configuration per site as possible but I naturally still use Zend_Config_Ini for settings. Zend_Registry is needed to keep the global scope clean and is used to store instantiated objects that need to be available throughtout the website logic.</p>
<p>I have been a bit particular on using ZF as often as possible on these sites. With few exceptions. Thus I also use Zend_Form, Zend_Locale, Zend_Translate, Zend_Cache and more. Zend_Cache is really a no brainer and mainly used to speed up translations. This is extremely easy as Zend_Translate and Zend_Locale both are connected to the cache with one simple method call each. It is not complete but how simple this is to setup is illustrated by the below code.</p>
<pre>$configuration = new Zend_Config_Ini(
    APPLICATION_PATH .'/config/app.ini',
    APPLICATION_ENVIRONMENT
);
$frontendOptions = array(
    'lifetime' =&gt; $config-&gt;cache-&gt;lifetime,
    'automatic_serialization' =&gt; true
);
$backendOptions = array('cache_dir' =&gt; $config-&gt;cache-&gt;dir);
$cache = Zend_Cache::factory(
    'Core',
    'File',
    $frontendOptions,
    $backendOptions
);

$conf_locale = $configuration-&gt;locale;
$locale = new Zend_Locale($conf_locale);
$locale-&gt;setCache($cache);

Zend_Translate::setCache($cache);
$translate = new Zend_Translate(
    'array',
    APPLICATION_PATH .'/config/translation-' . $conf_locale . '.php',
    $conf_locale
);
$translate-&gt;setLocale($conf_locale);</pre>
<p>Zend_Form have had a few problems in many versions of ZF. In my opinion it is also a bit bloated and limiting to be used all the way. (Even though I like the automatic connection to the translation functionality in Zend_Translate and the validation through Zend_Validate) So I have settled for a simpler way where I use Zend_Form fully for validation (with Zend_Validate) and then give the view access to the form through a Zend_Form subclass to be able to print the fields individually. I think this is easier to handle than all the overloading and coding needed to fully make Zend_Form create forms as I want them. Another good thing with the form classes is that they too are locale aware and are translated automatically by connecting them to Zend_Translate through the simple line <em>Zend_Form::setDefaultTranslator($translate);</em>. The sub classed Form utility class looks like below. The generated elements are translated automatically. Very convenient.</p>
<pre>class Custom_Form extends Zend_Form  {
    /**
     * Render a field
     * @param string $name The name of the form element
     */
    public function _e($name) {
        $e = $this-&gt;getElement($name);
        return ($e) ? $e-&gt;render() : "&lt;dt&gt;Error&lt;/dt&gt;&lt;dd&gt;Missing &lt;$name&gt; field element&lt;/dd&gt;";
    }
}</pre>
<p>Another thing needed for these sites are to keep the urls understandable and thus translated into the language used on the site. For this the routes, or paths, are kept in the translation file as well. The translated paths are then registered to the router through the use of Zend_Controller_Router_Route and Zend_Controller_Router_Route_Regex objects.</p>
<pre>$frontController = Zend_Controller_Front::getInstance();
$router = $frontController-&gt;getRouter();
$router-&gt;addRoute(
    'route_review',
    new Zend_Controller_Router_Route(
        $translate-&gt;translate('route_review'),
        array('controller' =&gt; 'review', 'action' =&gt; 'index')
    )
);</pre>
<p>For image manipulation I haven&#8217;t looked further than ImageMagick. After a bit of tweaking you get very good quality when producing different image sizes.</p>
<h2>Search</h2>
<p>Last but not least, on the backend that is, there&#8217;s the search engine. ZF have an implementation of Lucene through Zend_Search_Lucene (derived from the Apache Lucene project). This is the one time I haven&#8217;t gone with ZF as I very much like the <a href="http://www.sphinxsearch.com/">open source Sphinx search engine</a> as it is so easy to integrate with MySQL. So Sphinx get to power the search.</p>
<p>This is convenient for several reasons. MySQL is not a great full text search engine, Sphinx give you better weighted results. The main reason though is the performance. Sphinx is very fast in itself but for a site with heavier traffic it is as simple as moving the search backend to it&#8217;s own machine to get a performance increase.</p>
<h2>Frontend</h2>
<p>On the frontend there is as clean html as possible to make it easy to change the design with only CSS as well as manipulate the client side with JQuery. If it wouldn&#8217;t be for the Google map the site would actually be pretty useful even without no css style at all.</p>
<p>A good practice I learned just recently (remember I&#8217;m mostly a backend developer) is to base all javascript functionality on modules that are instantiated depending on element ids present in the html. This makes it a lot simpler to split the javascript functionality into manageble pieces and also makes it a lot easier to maintain.</p>
<p>There are functionality in the client side javascript used to display error messages and information. This makes it necessary to create one javascript file with translation stirngs for each language. The correct javascript translation file is chosen in the layout (template/view file) depending on the current locale.</p>
<p>The map used is (are there any alternatives) <a href="http://code.google.com/apis/maps/">Google Maps API</a>. I chose to completely initiate the map by scanning the actual data displayed on the page. This is possible through clean html markup and also means that if I choose to list ten reviews on a page instead of five nothing need to be changed at all in the frontend. Only a loop limit on the backend.</p>
<h2>Conclusion</h2>
<p>Well. No conclusion. This was just a very basic walkthrough of most of the different pieces needed to create a fairly simple Zend Framework based website. Mostly it was a walkthrough of the bootstrap&#8230; I still hope it is useful or at least interesting.</p>
<p>I know I find it interesting to read about other sites and the architecture and design behind them.</p>


<div class="shr-bookmarks shr-bookmarks-expand shr-bookmarks-center shr-bookmarks-bg-knowledge">
<ul class="socials">
		<li class="shr-comfeed">
			<a href="http://www.dotvoid.com/2009/10/site-architecture-based-on-zend-framework/feed" rel="nofollow" class="external" title="Subscribe to the comments for this post?">Subscribe to the comments for this post?</a>
		</li>
		<li class="shr-delicious">
			<a href="http://delicious.com/post?url=http://www.dotvoid.com/2009/10/site-architecture-based-on-zend-framework/&amp;title=Site+architecture+based+on+Zend+Framework" rel="nofollow" class="external" title="Share this on del.icio.us">Share this on del.icio.us</a>
		</li>
		<li class="shr-facebook">
			<a href="http://www.facebook.com/share.php?v=4&amp;src=bm&amp;u=http://www.dotvoid.com/2009/10/site-architecture-based-on-zend-framework/&amp;t=Site+architecture+based+on+Zend+Framework" rel="nofollow" class="external" title="Share this on Facebook">Share this on Facebook</a>
		</li>
		<li class="shr-googlebuzz">
			<a href="http://www.google.com/buzz/post?url=http://www.dotvoid.com/2009/10/site-architecture-based-on-zend-framework/&amp;imageurl=" rel="nofollow" class="external" title="Post on Google Buzz">Post on Google Buzz</a>
		</li>
		<li class="shr-linkedin">
			<a href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http://www.dotvoid.com/2009/10/site-architecture-based-on-zend-framework/&amp;title=Site+architecture+based+on+Zend+Framework&amp;summary=After%20working%20on%20the%20Swedish%20weather%20site%20klart.se%20for%20awhile%20I%20now%20work%20on%20my%20own%20projects%20again.%20So%20I%20have%20switched%20Codeigniter%20to%20Zend%20Framework%20again.%0D%0A%0D%0AAfter%20a%20trip%20to%20Dublin%20I%20finally%20launched%20the%20beginning%20of%20a%20new%20social%20tourist%20Dublin%20guide.%20It%20is%20exactly%20the%20same%20site%20as%20both%20the%20Swedish%20&amp;source=dotvoid.com" rel="nofollow" class="external" title="Share this on LinkedIn">Share this on LinkedIn</a>
		</li>
		<li class="shr-plaxo">
			<a href="http://www.plaxo.com/?share_link=http://www.dotvoid.com/2009/10/site-architecture-based-on-zend-framework/" rel="nofollow" class="external" title="Share this on Plaxo">Share this on Plaxo</a>
		</li>
		<li class="shr-stumbleupon">
			<a href="http://www.stumbleupon.com/submit?url=http://www.dotvoid.com/2009/10/site-architecture-based-on-zend-framework/&amp;title=Site+architecture+based+on+Zend+Framework" rel="nofollow" class="external" title="Stumble upon something good? Share it on StumbleUpon">Stumble upon something good? Share it on StumbleUpon</a>
		</li>
		<li class="shr-twitter">
			<a href="http://twitter.com/home?status=Site+architecture+based+on+Zend+Framework+-+http://b2l.me/wtxg5&amp;source=shareaholic" rel="nofollow" class="external" title="Tweet This!">Tweet This!</a>
		</li>
</ul>
<div style="clear:both;"></div>
</div>

]]></content:encoded>
			<wfw:commentRss>http://www.dotvoid.com/2009/10/site-architecture-based-on-zend-framework/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Reordering nested sets using PHP and Javascript</title>
		<link>http://www.dotvoid.com/2007/09/reordering-nested-sets-using-php-and-javascript/</link>
		<comments>http://www.dotvoid.com/2007/09/reordering-nested-sets-using-php-and-javascript/#comments</comments>
		<pubDate>Fri, 14 Sep 2007 10:29:47 +0000</pubDate>
		<dc:creator>Danne</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://www.commodi.com/?p=235</guid>
		<description><![CDATA[The adjancency method
Representing a tree of nodes, for example product categories, in a relational database is not hard. The most common way of doing it is to store a parentid with each node. This is also known as the adjacency list model. It is sometimes also referred to as the recursive model. Whatever the name [...]]]></description>
			<content:encoded><![CDATA[<h3>The adjancency method</h3>
<p>Representing a tree of nodes, for example product categories, in a relational database is not hard. The most common way of doing it is to store a parentid with each node. This is also known as the adjacency list model. It is sometimes also referred to as the recursive model. Whatever the name it is easy to grasp. It is very simple to insert and move nodes around but it is not an optimal solution if you often select the whole tree from the database for displaying on a web page as you need to recursively select all children of nodes.</p>
<h3>The nested set model</h3>
<p>A much better solution is the nested set model. In this model trees are represented as nested sets. Instead of using a parentid you have a left and right value for each node expressing the relationship to other nodes. A tree of nodes can look like this.</p>
<pre>        34
         |
         +--36
         |   |
         |   +--46
         |   |
         |   +--47
         |
         +--38
             |
            +--39</pre>
<p>The same data can be viewed more graphically as nested sets. This is also the way they are stored in the database. Notice how the left and right values are numbered in order from the outermost left to the outermost right.</p>
<pre>                            id:34
   +----------------------------------------------------+
   |             id:36                     id:38        |
   |   +------------------------+    +--------------+   |
   |   |    id:46      id:47    |    |     id:39    |   |
   |   |   +-----+    +-----+   |    |   +------+   |   |
  1|  2|  3|     |4  5|     |6  |7  8|  9|      |10 |11 |12
   |   |   +-----+    +-----+   |    |   +------+   |   |
   |   +------------------------+    +--------------+   |
   +----------------------------------------------------+</pre>
<p>In the database this is stored as in the following table.</p>
<pre> +----+-----+-----+
 | id | lft | rgt |
 +----+-----+-----+
 | 34 | 1   | 12  |
 | 36 | 2   |  7  |
 | 46 | 3   |  4  |
 | 47 | 5   |  6  |
 | 38 | 8   | 11  |
 | 39 | 9   | 10  |
 +----+-----+-----+</pre>
<p>This allow you to select the full tree with only one select statement. Normally you select the full list of nodes including the depth of each node as shown below in the small table containing id and depth. It is then easy to loop over the data in PHP to produce a nice tree in HTML/CSS.</p>
<p>The data below can be displayed as the the tree on right. The depth is in parenthesis.</p>
<pre> +----+-------+        34 (0)
 | id | depth |         |
 +----+-------+         +--36 (1)
 | 34 | 0     |         |   | 
 | 36 | 1     |         |   +--46 (2)
 | 46 | 2     |         |   |
 | 47 | 2     |         |   +--47 (2)
 | 38 | 1     |         |
 | 39 | 2     |         +--38 (1)
 +----+-------+             |
                            +--39 (2)</pre>
<p>Here is a more thorough article on <a href="http://dev.mysql.com/tech-resources/articles/hierarchical-data.html">how you use MySQL with nested sets</a>.</p>
<h3>On to the problem</h3>
<p>Last night I was working on an application that display a full tree where the user must be able to to drag and drop nodes to reorder the tree. The problem is that it is much more difficult to insert or reorder the tree using the nested set model.</p>
<p>For the actual html I produced nested ordered lists using the OL and LI html element so that it was easy to use with the excellent <a href="http://youmuppet.com/?page_id=9">MooTree script</a> based on <a href="http://www.mootools.net/">MooTools</a>. (It does seem to have trouble with the latest version of MooTools though.) After reordering the structure it was easy to extract the tree list including the depth of each node. I sent this to the PHP backend to be handled there. The text data I sent to the PHP backend then look like below.</p>
<pre> 34,0
 36,1
 46,2
 47,2
 38,1
 39,2</pre>
<p>As you can see it looks exactly like the data I selected from the database previously. So I had to create a function in PHP that took this indata and produced a list of nodes with the correct left and right values. This list is then looped over to update all the nodes in the database.</p>
<pre>function depth2nestedset($data)
{
  $lines = explode("\n", $data);
  $rows = array();
  $stack = array();

  $lft = 0;   // Left value
  $rgt = 0;   // Right value
  $plvl = -1; // Previous node level

  foreach($lines as $line) {
    list($id, $lvl) = explode(',', $line);

    // Skip empty/faulty lines
    if (trim($id) == '') {
      continue();
    }

    if ($lvl &gt; $plvl) {
      $lft++;
      $rgt = 0;
      array_push($stack, $id);
    }
    else if ($lvl == $plvl) {
      $pid = array_pop($stack);
      $rows[$pid][2] = $rows[$pid][1] + 1;
      $lft = $lft + 2;
      $rgt = 0;
      array_push($stack, $id);
    }
    else {
      $lft = $lft + ($plvl - $lvl) + 2;

      $diff = $plvl - $lvl + 1;
      for($n = 0; $n &lt; $diff; $n++) {
        $pid = array_pop($stack);
        $rows[$pid][2] = $lft - $diff + $n;
      }
      array_push($stack, $id);
    }

    $rows[$id] = array($id, $lft, $rgt);
    $plvl = $lvl;
  }

  $plvl++;
  $cnt = count($rows) * 2;
  $leftovers = count($stack);

  for($n = 0; $n &lt; $leftovers; $n++) {
    $pid = array_pop($stack);
    $rows[$pid][2] = $cnt - $plvl-- + $n;
  }

  return $rows;
}</pre>
<p>The resulting associated array that is returned looks like below.</p>
<pre>Array
(
    [34] =&gt; Array
        (
            [0] =&gt; 34
            [1] =&gt; 1
            [2] =&gt; 12
        )
    [36] =&gt; Array
        (
            [0] =&gt; 36
            [1] =&gt; 2
            [2] =&gt; 7
        )
    [46] =&gt; Array
        (
            [0] =&gt; 46
            [1] =&gt; 3
            [2] =&gt; 4
        )
    [47] =&gt; Array
        (
            [0] =&gt; 47
            [1] =&gt; 5
            [2] =&gt; 6
        )
    [38] =&gt; Array
        (
            [0] =&gt; 38
            [1] =&gt; 8
            [2] =&gt; 11
        )
    [39] =&gt; Array
        (
            [0] =&gt; 39
            [1] =&gt; 9
            [2] =&gt; 10
        )
)</pre>
<p>That makes the circle complete. From left/right values in the database to a node tree based on depths that is easy to manipulate in html and then back to left/right values. Hopefully this makes sense. Do you have a better solution or more examples on applications that do this I would love to hear about it.</p>


<div class="shr-bookmarks shr-bookmarks-expand shr-bookmarks-center shr-bookmarks-bg-knowledge">
<ul class="socials">
		<li class="shr-comfeed">
			<a href="http://www.dotvoid.com/2007/09/reordering-nested-sets-using-php-and-javascript/feed" rel="nofollow" class="external" title="Subscribe to the comments for this post?">Subscribe to the comments for this post?</a>
		</li>
		<li class="shr-delicious">
			<a href="http://delicious.com/post?url=http://www.dotvoid.com/2007/09/reordering-nested-sets-using-php-and-javascript/&amp;title=Reordering+nested+sets+using+PHP+and+Javascript" rel="nofollow" class="external" title="Share this on del.icio.us">Share this on del.icio.us</a>
		</li>
		<li class="shr-facebook">
			<a href="http://www.facebook.com/share.php?v=4&amp;src=bm&amp;u=http://www.dotvoid.com/2007/09/reordering-nested-sets-using-php-and-javascript/&amp;t=Reordering+nested+sets+using+PHP+and+Javascript" rel="nofollow" class="external" title="Share this on Facebook">Share this on Facebook</a>
		</li>
		<li class="shr-googlebuzz">
			<a href="http://www.google.com/buzz/post?url=http://www.dotvoid.com/2007/09/reordering-nested-sets-using-php-and-javascript/&amp;imageurl=" rel="nofollow" class="external" title="Post on Google Buzz">Post on Google Buzz</a>
		</li>
		<li class="shr-linkedin">
			<a href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http://www.dotvoid.com/2007/09/reordering-nested-sets-using-php-and-javascript/&amp;title=Reordering+nested+sets+using+PHP+and+Javascript&amp;summary=The%20adjancency%20method%0D%0ARepresenting%20a%20tree%20of%20nodes%2C%20for%20example%20product%20categories%2C%20in%20a%20relational%20database%20is%20not%20hard.%20The%20most%20common%20way%20of%20doing%20it%20is%20to%20store%20a%20parentid%20with%20each%20node.%20This%20is%20also%20known%20as%20the%20adjacency%20list%20model.%20It%20is%20sometimes%20also%20referred%20to%20as%20the%20recursive%20model.%20W&amp;source=dotvoid.com" rel="nofollow" class="external" title="Share this on LinkedIn">Share this on LinkedIn</a>
		</li>
		<li class="shr-plaxo">
			<a href="http://www.plaxo.com/?share_link=http://www.dotvoid.com/2007/09/reordering-nested-sets-using-php-and-javascript/" rel="nofollow" class="external" title="Share this on Plaxo">Share this on Plaxo</a>
		</li>
		<li class="shr-stumbleupon">
			<a href="http://www.stumbleupon.com/submit?url=http://www.dotvoid.com/2007/09/reordering-nested-sets-using-php-and-javascript/&amp;title=Reordering+nested+sets+using+PHP+and+Javascript" rel="nofollow" class="external" title="Stumble upon something good? Share it on StumbleUpon">Stumble upon something good? Share it on StumbleUpon</a>
		</li>
		<li class="shr-twitter">
			<a href="http://twitter.com/home?status=Reordering+nested+sets+using+PHP+and+Javascript+-+http://b2l.me/wt8gN&amp;source=shareaholic" rel="nofollow" class="external" title="Tweet This!">Tweet This!</a>
		</li>
</ul>
<div style="clear:both;"></div>
</div>

]]></content:encoded>
			<wfw:commentRss>http://www.dotvoid.com/2007/09/reordering-nested-sets-using-php-and-javascript/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>PHP 5.2 ajaxified</title>
		<link>http://www.dotvoid.com/2006/11/php-52-ajaxified/</link>
		<comments>http://www.dotvoid.com/2006/11/php-52-ajaxified/#comments</comments>
		<pubDate>Mon, 27 Nov 2006 23:07:12 +0000</pubDate>
		<dc:creator>Danne</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.commodi.com/?p=203</guid>
		<description><![CDATA[PHP 5.2.0 was released a few weeks ago. Apart from the usual bigger, better badder there are two small additions that I think are worth mentioning.

A new extension for JSON decoding and encoding enabled by default.
Hooks for tracking file uploads.

These features aren&#8217;t competing for the heavy weight title in the release notes. Still, having these [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.php.net/releases/5_2_0.php">PHP 5.2.0 was released</a> a few weeks ago. Apart from the usual bigger, better badder there are two small additions that I think are worth mentioning.</p>
<ol>
<li>A <a href="http://www.php.net/manual/en/ref.json.php">new extension for JSON</a> decoding and encoding enabled by default.</li>
<li>Hooks for tracking file uploads.</li>
</ol>
<p>These features aren&#8217;t competing for the heavy weight title in the release notes. Still, having these implemented in PHP makes it a lot easier to develop modern, more responsive, web based applications. JSON encoding have never been very hard but it makes sense to have native support in PHP. I have not tested the file uploads yet but being able to correctly display progress bars when uploading large files is definitely important when working with web applications.</p>


<div class="shr-bookmarks shr-bookmarks-expand shr-bookmarks-center shr-bookmarks-bg-knowledge">
<ul class="socials">
		<li class="shr-comfeed">
			<a href="http://www.dotvoid.com/2006/11/php-52-ajaxified/feed" rel="nofollow" class="external" title="Subscribe to the comments for this post?">Subscribe to the comments for this post?</a>
		</li>
		<li class="shr-delicious">
			<a href="http://delicious.com/post?url=http://www.dotvoid.com/2006/11/php-52-ajaxified/&amp;title=PHP+5.2+ajaxified" rel="nofollow" class="external" title="Share this on del.icio.us">Share this on del.icio.us</a>
		</li>
		<li class="shr-facebook">
			<a href="http://www.facebook.com/share.php?v=4&amp;src=bm&amp;u=http://www.dotvoid.com/2006/11/php-52-ajaxified/&amp;t=PHP+5.2+ajaxified" rel="nofollow" class="external" title="Share this on Facebook">Share this on Facebook</a>
		</li>
		<li class="shr-googlebuzz">
			<a href="http://www.google.com/buzz/post?url=http://www.dotvoid.com/2006/11/php-52-ajaxified/&amp;imageurl=" rel="nofollow" class="external" title="Post on Google Buzz">Post on Google Buzz</a>
		</li>
		<li class="shr-linkedin">
			<a href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http://www.dotvoid.com/2006/11/php-52-ajaxified/&amp;title=PHP+5.2+ajaxified&amp;summary=PHP%205.2.0%20was%20released%20a%20few%20weeks%20ago.%20Apart%20from%20the%20usual%20bigger%2C%20better%20badder%20there%20are%20two%20small%20additions%20that%20I%20think%20are%20worth%20mentioning.%0D%0A%0D%0A%09A%20new%20extension%20for%20JSON%20decoding%20and%20encoding%20enabled%20by%20default.%0D%0A%09Hooks%20for%20tracking%20file%20uploads.%0D%0A%0D%0AThese%20features%20aren%27t%20competing%20for%20the%20hea&amp;source=dotvoid.com" rel="nofollow" class="external" title="Share this on LinkedIn">Share this on LinkedIn</a>
		</li>
		<li class="shr-plaxo">
			<a href="http://www.plaxo.com/?share_link=http://www.dotvoid.com/2006/11/php-52-ajaxified/" rel="nofollow" class="external" title="Share this on Plaxo">Share this on Plaxo</a>
		</li>
		<li class="shr-stumbleupon">
			<a href="http://www.stumbleupon.com/submit?url=http://www.dotvoid.com/2006/11/php-52-ajaxified/&amp;title=PHP+5.2+ajaxified" rel="nofollow" class="external" title="Stumble upon something good? Share it on StumbleUpon">Stumble upon something good? Share it on StumbleUpon</a>
		</li>
		<li class="shr-twitter">
			<a href="http://twitter.com/home?status=PHP+5.2+ajaxified+-+http://b2l.me/wy3cs&amp;source=shareaholic" rel="nofollow" class="external" title="Tweet This!">Tweet This!</a>
		</li>
</ul>
<div style="clear:both;"></div>
</div>

]]></content:encoded>
			<wfw:commentRss>http://www.dotvoid.com/2006/11/php-52-ajaxified/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Accessible forms and unobtrusive javascript</title>
		<link>http://www.dotvoid.com/2006/02/accessible-forms-and-unobtrusive-javascript/</link>
		<comments>http://www.dotvoid.com/2006/02/accessible-forms-and-unobtrusive-javascript/#comments</comments>
		<pubDate>Thu, 09 Feb 2006 20:47:27 +0000</pubDate>
		<dc:creator>Danne</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[web design]]></category>

		<guid isPermaLink="false">http://www.commodi.com/?p=171</guid>
		<description><![CDATA[I usually try to separate backend logic from the user interface logic when creating new PHP applications. I am pro fat gui and usually have a lot of client side scripting going on. I mostly use AJAX or other remote scripting techniques to call actions defined in the PHP backend. In my latest PHP project, [...]]]></description>
			<content:encoded><![CDATA[<p>I usually try to separate backend logic from the user interface logic when creating new PHP applications. I am pro fat gui and usually have a lot of client side scripting going on. I mostly use AJAX or other remote scripting techniques to call actions defined in the PHP backend. In my latest PHP project, a timesheet application (because all the ones I find are crappy),  I went for a really accessible user interface. An interface where you don&#8217;t have to use the mouse for everything.</p>
<p>I don&#8217;t want any PHP mixed with my html. I don&#8217;t want javascript in there either which is why I like the unobtrusive way of adding javascript to my applications. So <a href="http://bennolan.com/behaviour/">behaviour</a> fits right into my world. Normally you scatter lots of onclick and other event handling attributes in the html like below.</p>
<pre>&lt;a href="#" onclick="myaction()"&gt;My action&lt;/a&gt;</pre>
<p>Instead I create rules with the help of behaviour that applies certain events to a specific element based on id or css class. This gives me really clean html and is good because I need to style links individually in CSS anyways.</p>
<pre>&lt;a href="#" id="myaction"&gt;My action&lt;/a&gt;</pre>
<pre>var sheetRules = {
    '#myaction': function(el) {
        el.onclick = handleMyAction;
    }
Behaviour.register(sheetRules);</pre>
<p>I also want to use access keys. I don&#8217;t want users to be forced using the mouse. So the html I want is below.</p>
<pre>&lt;a href="#" id="myaction" accesskey="m"&gt;My action&lt;/a&gt;</pre>
<p>Using the access key combination, ALT-m in case you&#8217;re using windows, is working great. It seems the browsers are intelligent enough to fire the onclick event instead of following the actual link. So it doesn&#8217;t ruin it for you even if you have a backup link in addition to the onlick handler in case the users have javascript turned off.</p>
<p>It is actually quite simple to create accessible applications that degrade gracefully.</p>


<div class="shr-bookmarks shr-bookmarks-expand shr-bookmarks-center shr-bookmarks-bg-knowledge">
<ul class="socials">
		<li class="shr-comfeed">
			<a href="http://www.dotvoid.com/2006/02/accessible-forms-and-unobtrusive-javascript/feed" rel="nofollow" class="external" title="Subscribe to the comments for this post?">Subscribe to the comments for this post?</a>
		</li>
		<li class="shr-delicious">
			<a href="http://delicious.com/post?url=http://www.dotvoid.com/2006/02/accessible-forms-and-unobtrusive-javascript/&amp;title=Accessible+forms+and+unobtrusive+javascript" rel="nofollow" class="external" title="Share this on del.icio.us">Share this on del.icio.us</a>
		</li>
		<li class="shr-facebook">
			<a href="http://www.facebook.com/share.php?v=4&amp;src=bm&amp;u=http://www.dotvoid.com/2006/02/accessible-forms-and-unobtrusive-javascript/&amp;t=Accessible+forms+and+unobtrusive+javascript" rel="nofollow" class="external" title="Share this on Facebook">Share this on Facebook</a>
		</li>
		<li class="shr-googlebuzz">
			<a href="http://www.google.com/buzz/post?url=http://www.dotvoid.com/2006/02/accessible-forms-and-unobtrusive-javascript/&amp;imageurl=" rel="nofollow" class="external" title="Post on Google Buzz">Post on Google Buzz</a>
		</li>
		<li class="shr-linkedin">
			<a href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http://www.dotvoid.com/2006/02/accessible-forms-and-unobtrusive-javascript/&amp;title=Accessible+forms+and+unobtrusive+javascript&amp;summary=I%20usually%20try%20to%20separate%20backend%20logic%20from%20the%20user%20interface%20logic%20when%20creating%20new%20PHP%20applications.%20I%20am%20pro%20fat%20gui%20and%20usually%20have%20a%20lot%20of%20client%20side%20scripting%20going%20on.%20I%20mostly%20use%20AJAX%20or%20other%20remote%20scripting%20techniques%20to%20call%20actions%20defined%20in%20the%20PHP%20backend.%20In%20my%20latest%20PHP%20pro&amp;source=dotvoid.com" rel="nofollow" class="external" title="Share this on LinkedIn">Share this on LinkedIn</a>
		</li>
		<li class="shr-plaxo">
			<a href="http://www.plaxo.com/?share_link=http://www.dotvoid.com/2006/02/accessible-forms-and-unobtrusive-javascript/" rel="nofollow" class="external" title="Share this on Plaxo">Share this on Plaxo</a>
		</li>
		<li class="shr-stumbleupon">
			<a href="http://www.stumbleupon.com/submit?url=http://www.dotvoid.com/2006/02/accessible-forms-and-unobtrusive-javascript/&amp;title=Accessible+forms+and+unobtrusive+javascript" rel="nofollow" class="external" title="Stumble upon something good? Share it on StumbleUpon">Stumble upon something good? Share it on StumbleUpon</a>
		</li>
		<li class="shr-twitter">
			<a href="http://twitter.com/home?status=Accessible+forms+and+unobtrusive+javascript+-+File: /data/app/webapp/functions.php<br />Line: 7<br />Message: Too many connections&amp;source=shareaholic" rel="nofollow" class="external" title="Tweet This!">Tweet This!</a>
		</li>
</ul>
<div style="clear:both;"></div>
</div>

]]></content:encoded>
			<wfw:commentRss>http://www.dotvoid.com/2006/02/accessible-forms-and-unobtrusive-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cross site scripting</title>
		<link>http://www.dotvoid.com/2005/10/cross-site-scripting/</link>
		<comments>http://www.dotvoid.com/2005/10/cross-site-scripting/#comments</comments>
		<pubDate>Wed, 26 Oct 2005 08:19:13 +0000</pubDate>
		<dc:creator>Danne</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[xss]]></category>

		<guid isPermaLink="false">http://www.commodi.com/?p=154</guid>
		<description><![CDATA[While looking around for cross site scripting resources I stumbled upon this &#8220;ha.ckers.org&#8221; site which is an excellent source for ideas on how to check for XSS vulnerabilities. I have seen it before but I obviously forgot to bookmark it. Now I saw the site listed in the top of  del.icio.us/tag/xss as well. Another good [...]]]></description>
			<content:encoded><![CDATA[<p>While looking around for cross site scripting resources I stumbled upon <a href="http://ha.ckers.org/xss.html">this &#8220;ha.ckers.org&#8221; site</a> which is an excellent source for ideas on how to check for XSS vulnerabilities. I have seen it before but I obviously forgot to bookmark it. Now I saw the site listed in the top of  <a href="http://del.icio.us/tag/xss">del.icio.us/tag/xss</a> as well. Another good site to checkout is the <a href="http://www.owasp.org/">http://www.owasp.org</a> and even though their <a href="http://www.owasp.org/software/validation.html">regex collection</a> is not very international it can be useful.</p>
<p>The most annoying thing is that the only user input I allow on my site, the comment form, is vulnerable. I guess I will have to fix that now. Immediately.</p>


<div class="shr-bookmarks shr-bookmarks-expand shr-bookmarks-center shr-bookmarks-bg-knowledge">
<ul class="socials">
		<li class="shr-comfeed">
			<a href="http://www.dotvoid.com/2005/10/cross-site-scripting/feed" rel="nofollow" class="external" title="Subscribe to the comments for this post?">Subscribe to the comments for this post?</a>
		</li>
		<li class="shr-delicious">
			<a href="http://delicious.com/post?url=http://www.dotvoid.com/2005/10/cross-site-scripting/&amp;title=Cross+site+scripting" rel="nofollow" class="external" title="Share this on del.icio.us">Share this on del.icio.us</a>
		</li>
		<li class="shr-facebook">
			<a href="http://www.facebook.com/share.php?v=4&amp;src=bm&amp;u=http://www.dotvoid.com/2005/10/cross-site-scripting/&amp;t=Cross+site+scripting" rel="nofollow" class="external" title="Share this on Facebook">Share this on Facebook</a>
		</li>
		<li class="shr-googlebuzz">
			<a href="http://www.google.com/buzz/post?url=http://www.dotvoid.com/2005/10/cross-site-scripting/&amp;imageurl=" rel="nofollow" class="external" title="Post on Google Buzz">Post on Google Buzz</a>
		</li>
		<li class="shr-linkedin">
			<a href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http://www.dotvoid.com/2005/10/cross-site-scripting/&amp;title=Cross+site+scripting&amp;summary=While%20looking%20around%20for%20cross%20site%20scripting%20resources%20I%20stumbled%20upon%20this%20%22ha.ckers.org%22%20site%20which%20is%20an%20excellent%20source%20for%20ideas%20on%20how%20to%20check%20for%20XSS%20vulnerabilities.%20I%20have%20seen%20it%20before%20but%20I%20obviously%20forgot%20to%20bookmark%20it.%20Now%20I%20saw%20the%20site%20listed%20in%20the%20top%20of%C2%A0%20del.icio.us%2Ftag%2Fxss%20&amp;source=dotvoid.com" rel="nofollow" class="external" title="Share this on LinkedIn">Share this on LinkedIn</a>
		</li>
		<li class="shr-plaxo">
			<a href="http://www.plaxo.com/?share_link=http://www.dotvoid.com/2005/10/cross-site-scripting/" rel="nofollow" class="external" title="Share this on Plaxo">Share this on Plaxo</a>
		</li>
		<li class="shr-stumbleupon">
			<a href="http://www.stumbleupon.com/submit?url=http://www.dotvoid.com/2005/10/cross-site-scripting/&amp;title=Cross+site+scripting" rel="nofollow" class="external" title="Stumble upon something good? Share it on StumbleUpon">Stumble upon something good? Share it on StumbleUpon</a>
		</li>
		<li class="shr-twitter">
			<a href="http://twitter.com/home?status=Cross+site+scripting+-+http://b2l.me/wy3cu&amp;source=shareaholic" rel="nofollow" class="external" title="Tweet This!">Tweet This!</a>
		</li>
</ul>
<div style="clear:both;"></div>
</div>

]]></content:encoded>
			<wfw:commentRss>http://www.dotvoid.com/2005/10/cross-site-scripting/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Aspect Oriented Programming and javascript</title>
		<link>http://www.dotvoid.com/2005/06/aspect-oriented-programming-and-javascript/</link>
		<comments>http://www.dotvoid.com/2005/06/aspect-oriented-programming-and-javascript/#comments</comments>
		<pubDate>Fri, 17 Jun 2005 14:45:31 +0000</pubDate>
		<dc:creator>Danne</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[aop]]></category>

		<guid isPermaLink="false">http://www.commodi.com/?p=48</guid>
		<description><![CDATA[
After investigating AOP a bit more I am convinced that the concept is well worth the effort. I really like object oriented architectures as I think it is a good way of modelling applications. I don&#8217;t like to overdo it though. In PHP projects I often end up with a few classes and a lot [...]]]></description>
			<content:encoded><![CDATA[<div class="preamble">
<p>After investigating AOP a bit more I am convinced that the concept is well worth the effort. I really like object oriented architectures as I think it is a good way of modelling applications. I don&#8217;t like to overdo it though. In PHP projects I often end up with a few classes and a lot of procedural code. Mostly structured but still procedural.</p>
<p>Anyway I felt it was time to do some experimenting. I recently released my Toxic framework <em>(Project is dead and gone)</em>, a javascript and PHP communication toolkit, which is object oriented in both ends. Toxic does not force me but it incurrage me to program program Javascript in a more object oriented fashion. I decided to see if aspects could be applied to the javascript end of things. I think it could be really useful in rich web applications which mostly depend heavily on javascript. As javascript does not support AOP I had to do some coding. As it turns out javascript is very suitable for some nifty AOP coding.</div>
<div class="itemview">
<h3>What I want</h3>
<p>I searched Google but could not find anything to my taste and so I started piecing together code that would allow me to do what I want. I want support for <em>introductions</em>. Introductions allow me to extend classes with additional functionality, both methods and properties. You could do that by inheritance but it is too crude and limited. I can add many introductions to one class or one introduction to several unrelated classes. With introductions you have more freedom.</p>
<p>I also want support for advices of course. An advice is a piece of code that you apply to methods that get executed automatically without explicitly calling it. There are three main types of advices I want to support; <em>before</em>, <em>after</em> and <em>around</em>. A before advice is executed before the actual method invocation. It can not cancel the actual method call though. An after advice is simply code that is run after the method invocation. The around advice is more exciting as it allows you to add code that is executed &#8220;around&#8221; the method invocation. The around advice also has the power to cancel the method invocation so that the method never even executes.</p>
<p>So introductions enable you to extend classes in a very flexible manner and advices can change the way methods are executed. This can even be done at execution.</p>
<h3>Classical problem/solution example</h3>
<p>A classical example where AOP makes sense is logging or tracing functionality. I don&#8217;t want to have all classes inherit from a debug logging class. I just don&#8217;t think it makes sense to add references to a logger class and then add conditional debugging code all over the place either.</p>
<p>The alternative is to create an introduction that adds logging capabilities to a class, any class that is. Then you create a before and after advice that logs the method invocation together with the parameters.</p>
<p>An extremely simple way of adding tracing capabilites without altering the functionality or code of the actual class or class methods.</p>
<h3>A &#8220;real&#8221; example</h3>
<p>Another example where AOP is nice could be in a content management system that needs locking of resources like documents, pages and media files.</p>
<p>Here is a simple javascript example class. It doesn&#8217;t contain any real funtionality but is enough to demonstrate the principles. (I use underscores as prefix to (semi) private properties and methods.)</p>
<pre>function Document(){}
Document.prototype = {
_id: 0,
_name: '',

name: function() {
  return this._name;
},

id: function() {
  return this._id;
},

save: function() {
   return true;
},

open: function(id) {
  this._id = id;
  this._name = 'Ajax on AOP steroids'
  return true;
}
}</pre>
<p>Lets say this is a wrapper class that is mapped to a server class via an ajax framework. The code that use this class could look like below.</p>
<pre>function openDocument(id)
{
  var doc = new Document();
  try {
    doc.open(id);
  }
  catch(e)
  {
    alert(e);
    return;
  }

  // Update icons and other user elements affected  alert("Doc id: " + doc.id());
  return doc;
}</pre>
<p>Now we want to add locking capabilities on Documents and all the other imaginary classes without altering them. If we can&#8217;t lock them we don&#8217;t want to open them for editing. When invoking open() on any of these objects locking should be automatically handled. This could involve both server calls as well as updating user interface elements. First we need to extend the class with locking functionality. This is handled by an introduction and one around advice.</p>
<p>The introduction looks like a class &#8211; and it is &#8211; but it contains only locking functionality. We could create many introductions like this without the need for aggregation or a fat base class. Anyway, the end result is an extended Document class.</p>
<pre>function Lockable(){}
Lockable.prototype = {
_locked: false,

  locked: function() {
    return this._locked;
  }
}</pre>
<p>When invoking the open() method on the Document class we want to have it locked automatically. We don&#8217;t want to change either the Document class or the code invoking the open() method. So we stick functionality to actually lock objects in the around advice. This advice is executed &#8220;around&#8221; the open() method. If locking fails an exception is thrown and the open method is never called. If locking succeeds proceed() is called. The proceed() method executes the originally invoked method and is specific to the AOP framework I&#8217;ve written. I have seen a Java AOP framework use that method name and I liked it.</p>
<pre>function lockOnOpen()
{
  // Lock this object        
  // If we didn't succeed
  throw (new Error ("Failed locking " + this._name));

  // The object is locked
  this._locked = true;

  var ret = proceed();     

  return ret;
}</pre>
<p>Last but not least we want to apply these aspects on the Document class (and any other class in question).  I haven&#8217;t written any advanced cross cuts regular expressions so this is a manual coding task. The Aspects object is available globally and defined in the framework.</p>
<pre>try {
  Aspects.addIntroduction(Lockable, Document);
  Aspects.addAround(lockOnOpen, Document, "open");
}
catch(e)
{
  alert(e);
}</pre>
<p>The code that opens a Document looks the same as before we added locking capabilities to our imaginary CMS. This is a great way of adding functionality with the least amount of effort and the least amount of impact on the application.</p>
<pre>function openDocument(id)
{
  var doc = new Document();
  try {
    doc.open(id);
  }
  catch(e)
  {
    alert(e);
    return;
  }

  // Update icons and other user elements affected
  alert("Doc id: " + doc.id());
  return doc;
}</pre>
<h3>The AOP framework</h3>
<p>To support this way of using aspects in javascript I have written a small framework, or utility class really, called Aspects. It supports the aforementioned introductions and three kinds of advices. It is also possible to chain several before and after advices together on one method. Just make sure you add around advices before you add the other two. When adding advices you must add an advice for one class at a time but you can send in an array of the methods of that class that the aspect should apply to.</p>
<h4>Public methods</h4>
<p>Jsclass is a reference to a javascript class which really is a javascript function object. Jsfunction is a reference to a normal function.</p>
<p><strong>addIntroduction</strong>(jsclass introduction, [jsclass | array] extendClass)<br />
<strong>addBefore</strong>(jsfunction advice, jsclass extendClass, [string | array] methodName)<br />
<strong>addAfter</strong>(jsfunction advice, jsclass extendClass, [string | array] methodName)<br />
<strong>addAround</strong>(jsfunction advice, jsclass extendClass, [string | array] methodName)</p>
<h4>Exceptions</h4>
<p>Three exceptions can be thrown:</p>
<p>InvalidAspect, InvalidObject and InvalidMethod</p>
<h4>The AOP framework code</h4>
<pre>InvalidAspect = new Error("Missing a valid aspect. Aspect is not a function.");
InvalidObject = new Error("Missing valid object or an array of valid objects.");
InvalidMethod = new Error("Missing valid method to apply aspect on.");

Aspects = new Object();

Aspects._addIntroduction = function(intro, obj)
{ for (var m in intro.prototype)
    {
      obj.prototype[m] = intro.prototype[m];
    }
}

Aspects.addIntroduction = function(aspect, objs)
{
  var oType = typeof(objs);

  if (typeof(aspect) != 'function')
    throw(InvalidAspect);

  if (oType == 'function')
  {
    this._addIntroduction(aspect, objs);
  }
  else if (oType == 'object')
  {
    for (var n = 0; n &lt; objs.length; n++)
    {
      this._addIntroduction(aspect, objs[n]);
    }
  }
  else
  {
    throw InvalidObject;
  }
}

Aspects.addBefore = function(aspect, obj, funcs)
{
  var fType = typeof(funcs);

  if (typeof(aspect) != 'function')
    throw(InvalidAspect);

  if (fType != 'object')
    funcs = Array(funcs);

  for (var n = 0; n &lt; funcs.length; n++)
  {
    var fName = funcs[n];
    var old = obj.prototype[fName];

    if (!old)
      throw InvalidMethod;

    obj.prototype[fName] = function() {
      aspect.apply(this, arguments);
      return old.apply(this, arguments);
    }
  }
}

Aspects.addAfter = function(aspect, obj, funcs)
{
  if (typeof(aspect) != 'function')
    throw InvalidAspect;

  if (typeof(funcs) != 'object')
    funcs = Array(funcs);

  for (var n = 0; n &lt; funcs.length; n++)
  {
    var fName = funcs[n];
    var old = obj.prototype[fName];

    if (!old)
      throw InvalidMethod;

    obj.prototype[fName] = function() {
      var args = old.apply(this, arguments);
      return ret = aspect.apply(this, Array(args, null));
    }
  }
}

Aspects._getLogic = function(func)
{
    var oSrc = new String(func);
    var nSrc = '';
    var n = 0;

    while (oSrc[n])
    {
      if (oSrc[n] == '\n' || oSrc[n] == '\r')
        nSrc[n++] += ' ';
      else
        nSrc += oSrc[n++];
    }

    n = 0;
    while (nSrc[n++] != '{');
    nSrc = nSrc.substring(n, nSrc.length - 1);
    return nSrc;
}

Aspects.addAround = function(aspect, obj, funcs)
{
  if (typeof(aspect) != 'function')
    throw InvalidAspect;

  if (typeof(funcs) != 'object')
    funcs = Array(funcs);

  var aSrc = this._getLogic(aspect);

  for (var n = 0; n &lt; funcs.length; n++)
  {
    var fName = funcs[n];
    if (!obj.prototype[fName])
      throw InvalidMethod;

    var oSrc = 'var original = ' + obj.prototype[fName];
    var fSrc = oSrc + aSrc.replace('proceed();',
                 'original.apply(this, arguments);');
    obj.prototype[fName] = Function(fSrc);
  }

  return true;
}</pre>
</div>


<div class="shr-bookmarks shr-bookmarks-expand shr-bookmarks-center shr-bookmarks-bg-knowledge">
<ul class="socials">
		<li class="shr-comfeed">
			<a href="http://www.dotvoid.com/2005/06/aspect-oriented-programming-and-javascript/feed" rel="nofollow" class="external" title="Subscribe to the comments for this post?">Subscribe to the comments for this post?</a>
		</li>
		<li class="shr-delicious">
			<a href="http://delicious.com/post?url=http://www.dotvoid.com/2005/06/aspect-oriented-programming-and-javascript/&amp;title=Aspect+Oriented+Programming+and+javascript" rel="nofollow" class="external" title="Share this on del.icio.us">Share this on del.icio.us</a>
		</li>
		<li class="shr-facebook">
			<a href="http://www.facebook.com/share.php?v=4&amp;src=bm&amp;u=http://www.dotvoid.com/2005/06/aspect-oriented-programming-and-javascript/&amp;t=Aspect+Oriented+Programming+and+javascript" rel="nofollow" class="external" title="Share this on Facebook">Share this on Facebook</a>
		</li>
		<li class="shr-googlebuzz">
			<a href="http://www.google.com/buzz/post?url=http://www.dotvoid.com/2005/06/aspect-oriented-programming-and-javascript/&amp;imageurl=" rel="nofollow" class="external" title="Post on Google Buzz">Post on Google Buzz</a>
		</li>
		<li class="shr-linkedin">
			<a href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http://www.dotvoid.com/2005/06/aspect-oriented-programming-and-javascript/&amp;title=Aspect+Oriented+Programming+and+javascript&amp;summary=%0D%0A%0D%0AAfter%20investigating%20AOP%20a%20bit%20more%20I%20am%20convinced%20that%20the%20concept%20is%20well%20worth%20the%20effort.%20I%20really%20like%20object%20oriented%20architectures%20as%20I%20think%20it%20is%20a%20good%20way%20of%20modelling%20applications.%20I%20don%27t%20like%20to%20overdo%20it%20though.%20In%20PHP%20projects%20I%20often%20end%20up%20with%20a%20few%20classes%20and%20a%20lot%20of%20procedu&amp;source=dotvoid.com" rel="nofollow" class="external" title="Share this on LinkedIn">Share this on LinkedIn</a>
		</li>
		<li class="shr-plaxo">
			<a href="http://www.plaxo.com/?share_link=http://www.dotvoid.com/2005/06/aspect-oriented-programming-and-javascript/" rel="nofollow" class="external" title="Share this on Plaxo">Share this on Plaxo</a>
		</li>
		<li class="shr-stumbleupon">
			<a href="http://www.stumbleupon.com/submit?url=http://www.dotvoid.com/2005/06/aspect-oriented-programming-and-javascript/&amp;title=Aspect+Oriented+Programming+and+javascript" rel="nofollow" class="external" title="Stumble upon something good? Share it on StumbleUpon">Stumble upon something good? Share it on StumbleUpon</a>
		</li>
		<li class="shr-twitter">
			<a href="http://twitter.com/home?status=Aspect+Oriented+Programming+and+javascript+-+http://b2l.me/wujgc&amp;source=shareaholic" rel="nofollow" class="external" title="Tweet This!">Tweet This!</a>
		</li>
</ul>
<div style="clear:both;"></div>
</div>

]]></content:encoded>
			<wfw:commentRss>http://www.dotvoid.com/2005/06/aspect-oriented-programming-and-javascript/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Announcing Toxic &#8211; an Ajax toolkit</title>
		<link>http://www.dotvoid.com/2005/05/announcing-toxic-an-ajax-toolkit/</link>
		<comments>http://www.dotvoid.com/2005/05/announcing-toxic-an-ajax-toolkit/#comments</comments>
		<pubDate>Tue, 24 May 2005 17:20:37 +0000</pubDate>
		<dc:creator>Danne</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[ajax]]></category>

		<guid isPermaLink="false">http://www.commodi.com/?p=132</guid>
		<description><![CDATA[
The project is no longer available. Might be so in the future.
Recently I have been working hard on my SRSS (whatever) project. The result is nearly finished and has been dubbed Toxic.
Toxic is an AJAX toolkit, or framework, for creating rich web applications. It handles the tedious and repetetive tasks involved in integrating a client [...]]]></description>
			<content:encoded><![CDATA[<div class="preamble">
<p><em>The project is no longer available. Might be so in the future.</em></p>
<p>Recently I have been working hard on my SRSS (whatever) project. The result is nearly finished and has been dubbed Toxic.</p>
<p>Toxic is an AJAX toolkit, or framework, for creating rich web applications. It handles the tedious and repetetive tasks involved in integrating a client created using html and javascript with a server backend. It enables client side javascript to directly call class methods in PHP5 (or any other suitable language). It also enables the server side PHP to directly call client side javascript functions. Using Toxic you can get rid of much of the tedious work in form intensive rich web applications.</p>
<p>UPDATE: Toxic has been release here (<em>Project is dead and gone</em>).</div>
<div class="itemview">
<h3>Overview</h3>
<p>Toxic is an AJAX toolkit, or framework, for creating rich web applications. It handles the tedious and repetetive tasks involved in integrating a client created using html and javascript with a server backend. Currently there is only a PHP5 backend available. It should be fairly straightforward to add backends in other languages.</p>
<p>Toxic handles the communication that takes place between the client and server. It can also be used to automate validation and sending of form fields in an application.</p>
<p>One difference between Toxic and other frameworks is that you do not need to generate code in any way.</p>
<p>Toxic can:</p>
<ul>
<li>Directly call methods in PHP classes from javascript.</li>
<li>Bind form fields to method calls with automatic validation.</li>
<li>Create callbacks that directly call javascript functions from the backend.</li>
<li>Automatically transform javascript variables to PHP parameters.</li>
<li>Send any javascript variable or object with associated keys.</li>
<li>Automatically transform PHP exceptions into javascript exceptions.</li>
</ul>
<h3>Synchronous/asynchronous</h3>
<p>The default mode for Toxic is synchronous. In this mode any exceptions on the server side will be automatically translated into a javascript exception.</p>
<p>If you want a call to be asynchronous you only need to bind a callback to a method call. All further calls to that specific method will be done asynchronously. When calls are made asynchronous a default timeout is used. This can be changed by a public property in the RemoteObject class.</p>
<h3>Multiple requests</h3>
<p>It is possible to have one RemoteObject that process several asynchronous calls concurrently. Using this excessively is not tested and probably not a good idea.</p>
<h3>Hard v soft callbacks</h3>
<p>Toxic let you create callbacks in two different modes. Hard callbacks are used by default and are also the simplest. A hard callback gives you the ability to create a javascript function with your own parameters. This javascript function is then called directly from the server side without any fuzz.</p>
<p>A soft callback gives you more control in that your javascript function only receive one parameter, the RemoteResult object. This gives you access to all the data received as well as the native request object with all the HTTP headers.</p>
<h3>Serialization</h3>
<p>All data transferred between client and server is serialized in a slimlined XML format. Before any server side code parses the data the XML is validated against a DTD to enforce the correct format. The format is inspired by <a href="http://jpspan.sourceforge.net/">JPSpan</a>.</p>
<pre>&lt;!ELEMENT class (a*|i*|d*|b*|n*|s*|u*)*&gt;
&lt;!ATTLIST class name CDATA #REQUIRED
                method CDATA #IMPLIED
                error CDATA #IMPLIED&gt;
&lt;!ELEMENT a (a*|i*|d*|b*|n*|s*|u*)*&gt;
&lt;!ATTLIST a id ID #IMPLIED
            k CDATA #IMPLIED&gt;
&lt;!ELEMENT i EMPTY&gt;
&lt;!ATTLIST i id ID #IMPLIED
            k CDATA #IMPLIED
            v CDATA #REQUIRED&gt;
&lt;!ELEMENT d EMPTY&gt;
&lt;!ATTLIST d id ID #IMPLIED
            k CDATA #IMPLIED
            v CDATA #REQUIRED&gt;
&lt;!ELEMENT b EMPTY&gt;
&lt;!ATTLIST b id ID #IMPLIED
            k CDATA #IMPLIED
            v CDATA #REQUIRED&gt;
&lt;!ELEMENT n EMPTY&gt;
&lt;!ATTLIST n id ID #IMPLIED
            k CDATA #IMPLIED&gt;
&lt;!ELEMENT s (#PCDATA)&gt;
&lt;!ATTLIST s id ID #IMPLIED
            k CDATA #IMPLIED&gt;
&lt;!ELEMENT u (#PCDATA)&gt;
&lt;!ATTLIST u id ID #IMPLIED
            k CDATA #IMPLIED&gt;</pre>
<h3>Validation &amp; sanitizing</h3>
<p>Using Toxic does make things easier on the server side. You don&#8217;t have to deal with all the $_POST/$_GET variables. The XML serialization format is enforced by a DTD.</p>
<p>Still Toxic does not free the receiving method of the task to properly validate and sanitize incoming parameter values.</p>
<h3>GET, POST and rfc 2616</h3>
<p>What about <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html">rfc 2616</a> and HTTP status then? It is said that the GET method should never result in data being altered. Toxic use the POST method only. This could be called cheating but hey <img src='http://www.dotvoid.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> . <a href="http://www.dotvoid.com/view.php?id=38">Read more on this topic&#8230;</a></div>


<div class="shr-bookmarks shr-bookmarks-expand shr-bookmarks-center shr-bookmarks-bg-knowledge">
<ul class="socials">
		<li class="shr-comfeed">
			<a href="http://www.dotvoid.com/2005/05/announcing-toxic-an-ajax-toolkit/feed" rel="nofollow" class="external" title="Subscribe to the comments for this post?">Subscribe to the comments for this post?</a>
		</li>
		<li class="shr-delicious">
			<a href="http://delicious.com/post?url=http://www.dotvoid.com/2005/05/announcing-toxic-an-ajax-toolkit/&amp;title=Announcing+Toxic+-+an+Ajax+toolkit" rel="nofollow" class="external" title="Share this on del.icio.us">Share this on del.icio.us</a>
		</li>
		<li class="shr-facebook">
			<a href="http://www.facebook.com/share.php?v=4&amp;src=bm&amp;u=http://www.dotvoid.com/2005/05/announcing-toxic-an-ajax-toolkit/&amp;t=Announcing+Toxic+-+an+Ajax+toolkit" rel="nofollow" class="external" title="Share this on Facebook">Share this on Facebook</a>
		</li>
		<li class="shr-googlebuzz">
			<a href="http://www.google.com/buzz/post?url=http://www.dotvoid.com/2005/05/announcing-toxic-an-ajax-toolkit/&amp;imageurl=" rel="nofollow" class="external" title="Post on Google Buzz">Post on Google Buzz</a>
		</li>
		<li class="shr-linkedin">
			<a href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http://www.dotvoid.com/2005/05/announcing-toxic-an-ajax-toolkit/&amp;title=Announcing+Toxic+-+an+Ajax+toolkit&amp;summary=%0D%0A%0D%0AThe%20project%20is%20no%20longer%20available.%20Might%20be%20so%20in%20the%20future.%0D%0A%0D%0ARecently%20I%20have%20been%20working%20hard%20on%20my%20SRSS%20%28whatever%29%20project.%20The%20result%20is%20nearly%20finished%20and%20has%20been%20dubbed%20Toxic.%0D%0A%0D%0AToxic%20is%20an%20AJAX%20toolkit%2C%20or%20framework%2C%20for%20creating%20rich%20web%20applications.%20It%20handles%20the%20tedious%20and%20re&amp;source=dotvoid.com" rel="nofollow" class="external" title="Share this on LinkedIn">Share this on LinkedIn</a>
		</li>
		<li class="shr-plaxo">
			<a href="http://www.plaxo.com/?share_link=http://www.dotvoid.com/2005/05/announcing-toxic-an-ajax-toolkit/" rel="nofollow" class="external" title="Share this on Plaxo">Share this on Plaxo</a>
		</li>
		<li class="shr-stumbleupon">
			<a href="http://www.stumbleupon.com/submit?url=http://www.dotvoid.com/2005/05/announcing-toxic-an-ajax-toolkit/&amp;title=Announcing+Toxic+-+an+Ajax+toolkit" rel="nofollow" class="external" title="Stumble upon something good? Share it on StumbleUpon">Stumble upon something good? Share it on StumbleUpon</a>
		</li>
		<li class="shr-twitter">
			<a href="http://twitter.com/home?status=Announcing+Toxic+-+an+Ajax+toolkit+-+http://b2l.me/wwfkc&amp;source=shareaholic" rel="nofollow" class="external" title="Tweet This!">Tweet This!</a>
		</li>
</ul>
<div style="clear:both;"></div>
</div>

]]></content:encoded>
			<wfw:commentRss>http://www.dotvoid.com/2005/05/announcing-toxic-an-ajax-toolkit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google Web Accelerator</title>
		<link>http://www.dotvoid.com/2005/05/google-web-accelerator/</link>
		<comments>http://www.dotvoid.com/2005/05/google-web-accelerator/#comments</comments>
		<pubDate>Thu, 12 May 2005 10:08:28 +0000</pubDate>
		<dc:creator>Danne</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[apache]]></category>

		<guid isPermaLink="false">http://www.commodi.com/?p=129</guid>
		<description><![CDATA[
Recently the Google Web Accelerator (GWA)has received a lot of attention from web application developers. Rightly so. When installing GWA for use in your browser it speeds up surfing by prefetching pages. This can be very useful but also extremely dangerous as it has very bad side effects on many (badly designed) web applications. Why? [...]]]></description>
			<content:encoded><![CDATA[<div class="preamble">
<p>Recently the <a href="http://webaccelerator.google.com/">Google Web Accelerator</a> (GWA)has received a lot of attention from web application developers. Rightly so. When installing GWA for use in your browser it speeds up surfing by prefetching pages. This can be very useful but also extremely dangerous as it has very bad side effects on many (badly designed) web applications. Why? When you open up a web page GWA scans through the page looking for all the links and prefetch all the pages pointed to by the links. This is where things can go really wrong&#8230;</div>
<div class="itemview">
<p>The reason is that many web developers don&#8217;t have a clue about the difference between the http methods GET and POST. Some know approximately the technical difference but not why one should use one method over the other. According to <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html">the RFC</a> the GET method should never &#8220;alter the world&#8221;. In other words &#8211; POST should be used whenever there is a need to alter data and GET should only ever be used to fetch data.</p>
<p>So what does this have to do the Google Web Accelerator? It is very common in web applications to present, for example, lists of data like users or articles with links to either display or delete the data.</p>
<p>Consider what happens if the application user has GWA installed when all the links are prefetched. All the links will be invisibly followed and all data deleted. Many applications protect links like this with onclick handlers that ask the user if they want to delete the data. As the GWA has no concept of javascript it just ignores this fact and the links will be prefetched anyway with potentially disastrous results.</p>
<p>It is not Google that has done anything wrong. They follow the guidelines in the RFC on the correct usage of GET and POST.</p>
<p>Personally I think my applications are safe. I usually follow the guidelines on GET and POST but not always. But as I use only javascript calls to fetch or do things in my applications I am safe.</p>
<p>Safe</p>
<pre>&lt;a href="#" onclick="deleteUser(372);"&gt;Delete user&lt;/a&gt;</pre>
<p>Very dangerous (and wrong)</p>
<pre>&lt;a href="deleteUser.php?id=372"&gt;Delete user&lt;/a&gt;</pre>
<p>A safeguard for Apache</p>
<pre>RewriteCond %{HTTP:x-moz} ^prefetch
RewriteRule ^/*admin/.* - [F,L]</pre>
<p>I found the Apache solution on the blog of <a href="http://blog.bitflux.ch/archive/2005/05/12/prevent-prefetching-from-google-s-web-accelerator.html">Christian Stocker</a> who got it from the <a href="http://syntaxblog.forumone.com/archives/66-Google-Web-Accelerator-Fix-in-CVS.html">Syntax CMS blog</a> through <a href="http://planet.oscom.org/">Planet OSCOM</a>. (The blogging world of today&#8230;) Anyway, it is most likely a good idea to review your applications before users of your applications starts using GWA and this becomes a serious issue.</div>
<p><a name="comments"></a></p>


<div class="shr-bookmarks shr-bookmarks-expand shr-bookmarks-center shr-bookmarks-bg-knowledge">
<ul class="socials">
		<li class="shr-comfeed">
			<a href="http://www.dotvoid.com/2005/05/google-web-accelerator/feed" rel="nofollow" class="external" title="Subscribe to the comments for this post?">Subscribe to the comments for this post?</a>
		</li>
		<li class="shr-delicious">
			<a href="http://delicious.com/post?url=http://www.dotvoid.com/2005/05/google-web-accelerator/&amp;title=Google+Web+Accelerator" rel="nofollow" class="external" title="Share this on del.icio.us">Share this on del.icio.us</a>
		</li>
		<li class="shr-facebook">
			<a href="http://www.facebook.com/share.php?v=4&amp;src=bm&amp;u=http://www.dotvoid.com/2005/05/google-web-accelerator/&amp;t=Google+Web+Accelerator" rel="nofollow" class="external" title="Share this on Facebook">Share this on Facebook</a>
		</li>
		<li class="shr-googlebuzz">
			<a href="http://www.google.com/buzz/post?url=http://www.dotvoid.com/2005/05/google-web-accelerator/&amp;imageurl=" rel="nofollow" class="external" title="Post on Google Buzz">Post on Google Buzz</a>
		</li>
		<li class="shr-linkedin">
			<a href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http://www.dotvoid.com/2005/05/google-web-accelerator/&amp;title=Google+Web+Accelerator&amp;summary=%0D%0A%0D%0ARecently%20the%20Google%20Web%20Accelerator%20%28GWA%29has%20received%20a%20lot%20of%20attention%20from%20web%20application%20developers.%20Rightly%20so.%20When%20installing%20GWA%20for%20use%20in%20your%20browser%20it%20speeds%20up%20surfing%20by%20prefetching%20pages.%20This%20can%20be%20very%20useful%20but%20also%20extremely%20dangerous%20as%20it%20has%20very%20bad%20side%20effects%20on%20man&amp;source=dotvoid.com" rel="nofollow" class="external" title="Share this on LinkedIn">Share this on LinkedIn</a>
		</li>
		<li class="shr-plaxo">
			<a href="http://www.plaxo.com/?share_link=http://www.dotvoid.com/2005/05/google-web-accelerator/" rel="nofollow" class="external" title="Share this on Plaxo">Share this on Plaxo</a>
		</li>
		<li class="shr-stumbleupon">
			<a href="http://www.stumbleupon.com/submit?url=http://www.dotvoid.com/2005/05/google-web-accelerator/&amp;title=Google+Web+Accelerator" rel="nofollow" class="external" title="Stumble upon something good? Share it on StumbleUpon">Stumble upon something good? Share it on StumbleUpon</a>
		</li>
		<li class="shr-twitter">
			<a href="http://twitter.com/home?status=Google+Web+Accelerator+-+http://b2l.me/wyupx&amp;source=shareaholic" rel="nofollow" class="external" title="Tweet This!">Tweet This!</a>
		</li>
</ul>
<div style="clear:both;"></div>
</div>

]]></content:encoded>
			<wfw:commentRss>http://www.dotvoid.com/2005/05/google-web-accelerator/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Remote Scripting (AJAX) framework</title>
		<link>http://www.dotvoid.com/2005/03/remote-scripting-ajax-framework/</link>
		<comments>http://www.dotvoid.com/2005/03/remote-scripting-ajax-framework/#comments</comments>
		<pubDate>Wed, 30 Mar 2005 15:15:28 +0000</pubDate>
		<dc:creator>Danne</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[remote scripting]]></category>

		<guid isPermaLink="false">http://www.commodi.com/?p=45</guid>
		<description><![CDATA[
Spare time to spend on interesting projects is not plentiful nowadays. Even so I have managed to put quite a few hours into a small web application framework. My goal is to make it easier to develop web applications that heavily depend on client server communication. I really want to get rid of the painfully [...]]]></description>
			<content:encoded><![CDATA[<div class="preamble">
<p>Spare time to spend on interesting projects is not plentiful nowadays. Even so I have managed to put quite a few hours into a small web application framework. My goal is to make it easier to develop web applications that heavily depend on client server communication. I really want to get rid of the painfully boring and repetetive task of validating form data and sending it to a backend in PHP where the data has to be validated again. The framework is based on XMLHttpRequest for the communication between the client and the server. This kind of communication is commonly known as Remote Scripting. Some people (not me) likes to use the new, more catchy, acronym AJAX. Anyway, this is a sneak peak on how the framework will be used.</p></div>
<h3>Introduction</h3>
<p>First I had a look at JPSpan and other similar implementations. Impressive as JPSpan is, I thought it a bit too much for me. I don&#8217;t need, or want, transparancy between javascript and PHP classes. To be honest, I really don&#8217;t like hiding the communication between client and server as it mostly creates problems. Pretending that the network isn&#8217;t there usually gives birth to architectures with a huge amount of method calls over the network. It is better to work with data on the client side, validate it and then send it to the server for the real work. However I did like the serialization into a streamlined XML format and thus I have adapted that in my solution.</p>
<p>The framework which has the wonderfully dry working name of SSRS is getting more and more complicated. I started working on a simple synchronous http communication between javascript and PHP. Now I am ending up with a framework for binding form fields to method calls with automatic validation of data. Still I think it is going to be really useful when production ready.</p>
<h3>The HTML form</h3>
<p>What is it then and what you do you do with it you ask? To show it off a bit I&#8217;ll give you a simple example. The below form is an extremely simple user form. It features a readonly field for the unique user id which of course will be empty when we create new users. When I use this form to create a new user I don&#8217;t want the page to reload. It is unecessary slow. But I still want the User_id field populated when the user has been saved.</p>
<pre>&lt;form id="User" onsubmit="return saveUser();"&gt;
&lt;fieldset&gt;
    &lt;legend&gt;User details&lt;/legend&gt;

    &lt;label id="lbl_User_id"&gt;Userid&lt;/label&gt;
    &lt;input type="text" readonly="1" id="User_id" /&gt;

    &lt;label id="lbl_User_login"&gt;User login&lt;/label&gt;
    &lt;input type="text" id="User_login" /&gt;

    &lt;label id="lbl_User_email"&gt;Email&lt;/label&gt;
    &lt;input type="text" id="User_email" /&gt;
    &lt;a href="#" onclick="return saveUser();"&gt;Save&lt;/a&gt;
&lt;/fieldset&gt;
&lt;/form&gt;</pre>
<p>I have added an onsubmit handler and a link that both call the javascript function saveUser(). I could just as well have used a normal submit button.</p>
<h3>The PHP class</h3>
<p>To handle users I have created a User class implemented in PHP. The class have a save() method that takes id, login and email as parameters. The id is not mandatory. To be able to return more data than just a value, result data is always returned as key value pairs in an array. When errors or problems are encountered exceptions are thrown which automatically will be passed to the client as javascript exceptions.</p>
<pre>class User
{
  public function save($id, $login, $email)
  {
    if ($id == null || $id == 0)
      {
        error_log("Creating new user");
        // Validate data
        // Save user
        // Retrieve the new numerical user id in $id
        $id = 1; // For the example
        return Array('id' =&gt; $id);
      }
    throw new Exception("Updating a user is not implemented");
  }
}</pre>
<h3>Tying them together</h3>
<p>So what do I as a developer need to do to connect these two loose ends? Before we create the saveUser() function mentioned above we need to setup the form against SSRS. A few lines of javascript in an onload handler or an explicitly called init function is needed.</p>
<pre>var g_user = null;
var frm = null;

frm = new Array(
	new Array('User_id', 'number', '', '', false, '', ''),
	new Array('User_login', 'string', 'A unique login',
		'Login not valid or not unique', true, 4, 8, ''),
	new Array('User_email', 'email', 'Email address is required',
		'Email is not valid', true));

g_user = new RemoteObject('postHandler.php', 'User');
g_user.bindFields(frm);
g_user.bindParams('save', 'User_id', 'User_login', 'User_email');</pre>
<p>What the above essentially does is:</p>
<ol>
<li>Create the client object and tell it what server class to use and which URI to communicate with. The postHandler.php is the backend implementation.</li>
<li>Create a structure that describes field data types, help and error messages, max/min length, etc.</li>
<li>Bind the form to the client object and bind form fields as parameters to method calls.</li>
</ol>
<p>The framework can handle strings, numbers, decimals, emails, string lists and more. For each datatype it is possible to set various constraints. For some datatypes it is also possible to specify your own regular expression to use as validation.</p>
<p>When this is done we can create the actual saveUser() function.</p>
<pre>function saveUser()
{
  var result;
  try
    {
      result = g_user.execute('save');
      document.getElementById('User_id').value = result.item(0);
    }
  catch(ex)
    {
      alert(ex.message);
    }
  return false;
}</pre>
<p>That is all. As we have bound the form to the g_user object all the fields are validated prior to being sent to the server. The error messages specified for the fields above will be displayed if needed. Any exception on the server side will also be displayed in the same way. As the fields User_id, User_login and User_email are bound to the save method they will automatically be handed over the PHP method save() in the User class.</p>
<h3>Conclusion</h3>
<p>The data being sent between client and server is encoded in a simple streamlined XML format and is always validated against a DTD to ensure the data is encoded correctly. This does not mean that you don&#8217;t need to check the data on the server side but it does add an extra layer of data security. It is also a lot simpler to validate the parameters in a method, where it should be done, than filtering $_GET or $_POST arrays before calling PHP functions or methods.</p>
<p>The benefits of using a framework like this is that it lets the developer concentrate on the functionality. Another benefit is that it does not interfere with your choice of template engine. I have a few things left to iron out before I release the code.</p>


<div class="shr-bookmarks shr-bookmarks-expand shr-bookmarks-center shr-bookmarks-bg-knowledge">
<ul class="socials">
		<li class="shr-comfeed">
			<a href="http://www.dotvoid.com/2005/03/remote-scripting-ajax-framework/feed" rel="nofollow" class="external" title="Subscribe to the comments for this post?">Subscribe to the comments for this post?</a>
		</li>
		<li class="shr-delicious">
			<a href="http://delicious.com/post?url=http://www.dotvoid.com/2005/03/remote-scripting-ajax-framework/&amp;title=Remote+Scripting+%28AJAX%29+framework" rel="nofollow" class="external" title="Share this on del.icio.us">Share this on del.icio.us</a>
		</li>
		<li class="shr-facebook">
			<a href="http://www.facebook.com/share.php?v=4&amp;src=bm&amp;u=http://www.dotvoid.com/2005/03/remote-scripting-ajax-framework/&amp;t=Remote+Scripting+%28AJAX%29+framework" rel="nofollow" class="external" title="Share this on Facebook">Share this on Facebook</a>
		</li>
		<li class="shr-googlebuzz">
			<a href="http://www.google.com/buzz/post?url=http://www.dotvoid.com/2005/03/remote-scripting-ajax-framework/&amp;imageurl=" rel="nofollow" class="external" title="Post on Google Buzz">Post on Google Buzz</a>
		</li>
		<li class="shr-linkedin">
			<a href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http://www.dotvoid.com/2005/03/remote-scripting-ajax-framework/&amp;title=Remote+Scripting+%28AJAX%29+framework&amp;summary=%0D%0A%0D%0ASpare%20time%20to%20spend%20on%20interesting%20projects%20is%20not%20plentiful%20nowadays.%20Even%20so%20I%20have%20managed%20to%20put%20quite%20a%20few%20hours%20into%20a%20small%20web%20application%20framework.%20My%20goal%20is%20to%20make%20it%20easier%20to%20develop%20web%20applications%20that%20heavily%20depend%20on%20client%20server%20communication.%20I%20really%20want%20to%20get%20rid%20of%20&amp;source=dotvoid.com" rel="nofollow" class="external" title="Share this on LinkedIn">Share this on LinkedIn</a>
		</li>
		<li class="shr-plaxo">
			<a href="http://www.plaxo.com/?share_link=http://www.dotvoid.com/2005/03/remote-scripting-ajax-framework/" rel="nofollow" class="external" title="Share this on Plaxo">Share this on Plaxo</a>
		</li>
		<li class="shr-stumbleupon">
			<a href="http://www.stumbleupon.com/submit?url=http://www.dotvoid.com/2005/03/remote-scripting-ajax-framework/&amp;title=Remote+Scripting+%28AJAX%29+framework" rel="nofollow" class="external" title="Stumble upon something good? Share it on StumbleUpon">Stumble upon something good? Share it on StumbleUpon</a>
		</li>
		<li class="shr-twitter">
			<a href="http://twitter.com/home?status=Remote+Scripting+%28AJAX%29+framework+-+http://b2l.me/wy3cx&amp;source=shareaholic" rel="nofollow" class="external" title="Tweet This!">Tweet This!</a>
		</li>
</ul>
<div style="clear:both;"></div>
</div>

]]></content:encoded>
			<wfw:commentRss>http://www.dotvoid.com/2005/03/remote-scripting-ajax-framework/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
