<?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>klog &#187; kfm</title>
	<atom:link href="http://verens.com/archives/category/web-development/kaes-file-manager/feed/" rel="self" type="application/rss+xml" />
	<link>http://verens.com</link>
	<description>php, linux, ajax, javascript, kae verens</description>
	<lastBuildDate>Mon, 01 Feb 2010 10:57:06 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>what&#8217;s up!</title>
		<link>http://verens.com/archives/2010/01/27/whats-up/</link>
		<comments>http://verens.com/archives/2010/01/27/whats-up/#comments</comments>
		<pubDate>Wed, 27 Jan 2010 09:35:53 +0000</pubDate>
		<dc:creator>Kae Verens</dc:creator>
				<category><![CDATA[ajax]]></category>
		<category><![CDATA[areyoumad]]></category>
		<category><![CDATA[book]]></category>
		<category><![CDATA[depression]]></category>
		<category><![CDATA[general]]></category>
		<category><![CDATA[kfm]]></category>
		<category><![CDATA[life]]></category>
		<category><![CDATA[music]]></category>
		<category><![CDATA[packt]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[piano]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://verens.com/?p=958</guid>
		<description><![CDATA[<p>Short run-down of what I&#8217;m doing lately: nothing.</p>
<p>Less short: I&#8217;m trying to get work out the door, get a good run at some personal projects, pass grade 2 piano, get organised, and generally improve my lot.</p>
<p>None of this is working. I think the &#8220;get organised&#8221; bit is the most important, as it will help the [...]]]></description>
			<content:encoded><![CDATA[<p>Short run-down of what I&#8217;m doing lately: nothing.</p>
<p>Less short: I&#8217;m trying to get work out the door, get a good run at some personal projects, pass grade 2 piano, get organised, and generally improve my lot.</p>
<p>None of this is working. I think the &#8220;get organised&#8221; bit is the most important, as it will help the rest of it fall into place.</p>
<p>I usually only post about web-development-related topics here, as that&#8217;s the only subject where I feel I can contribute something new and interesting, so I tend to not talk about other stuff. But sometimes, rattling off the current state of the head is good for clearing it.</p>
<p>In work, I can&#8217;t really complain &#8211; we have a number of largish projects which are slowly creeping towards completion. The hardest thing about them is getting information from the clients, and then a week or two later being told that half the information is not required. I guess my main complaint at work is the inexorably slow completion rate.</p>
<p>On the personal projects side:</p>
<p>There are still a number of small bugs in <a href="http://kfm.verens.com/">KFM 1.4</a>, and either I don&#8217;t have the time to get to them, or there is no enough information to recreate the bug and the submitter doesn&#8217;t give me access to their copy so I can&#8217;t see it from their side.</p>
<p>KFM 2 has been halted for a while &#8211; the idea is huge, but I simply don&#8217;t have the time, and no-one is clambering for it. I&#8217;ll get to it when I have time, but I might have to approach it by evolving KFM 1.x into meeting what I wanted, instead of the original goal of building KFM 2 from scratch.</p>
<p>I started a new project, <a href="http://www.oddjobs4locals.com/">OddJobs4Locals</a> two weeks back, and got a good two-day run at it, then time got ahead of me again. I think this will be a good one, when I can complete it. Useful for students, people with a little spare time, or simply people that just want to make a little extra cash. Not yet working, but it will be soon, I hope&#8230; This is doubly interesting to me, as it is done purely through AJAX, so it will be easy to do a smart-phone client or a desktop client when the time comes.</p>
<p>I&#8217;m in the back/forth stage of working with Packt publishing to see if they want me to do a second book (<a href="http://verens.com/archives/2009/12/13/jquery-1-3-with-php-buy-it/">the first one has no bad reviews at all</a>). We&#8217;ve mostly agreed on a table of contents, and I&#8217;m just trying to get the time to combine a few of the smaller chapters together.</p>
<p>On the piano, I&#8217;ve been ready for the grade 2 exam since November, and am still waiting to see if there will be an exam near me any time soon &#8211; I hate the effort that goes into travelling (I have a family, and no car). I was hoping to do a grade every 6 months. It looks like this might not be possible, despite me being ready for it&#8230; The tunes I&#8217;m doing for it are <a href="http://www.youtube.com/watch?v=ASdAX7ws_H8">Beethoven&#8217;s Sonatina in G Major</a>, <a href="http://www.youtube.com/watch?v=FQFRx-y2tJc">a waltz by Bela Bartok</a>, and Boys And Girls Come Out To Samba, by Terence Greaves &#8211; by the way, I don&#8217;t like those videos; there are no dynamics in any of them, and I can hear a number of mistakes as well. No video apparently of the Terence Greaves one.</p>
<p>As for organisation&#8230; well I guess I&#8217;d better start working with Mantis again.</p>
<p>My lot will have to wait &#8211; I&#8217;ve a load of work to get done before it <em>can</em> improve.</p>
<p>Meh. Depression taking hold again.</p>
]]></content:encoded>
			<wfw:commentRss>http://verens.com/archives/2010/01/27/whats-up/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>multiple file uploads using HTML5</title>
		<link>http://verens.com/archives/2009/12/28/multiple-file-uploads-using-html5/</link>
		<comments>http://verens.com/archives/2009/12/28/multiple-file-uploads-using-html5/#comments</comments>
		<pubDate>Mon, 28 Dec 2009 16:37:38 +0000</pubDate>
		<dc:creator>Kae Verens</dc:creator>
				<category><![CDATA[ajax]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[kfm]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://verens.com/?p=945</guid>
		<description><![CDATA[<p>As a response to a reported bug where Chrome was taking ages to load up a flash multiple-file uploader, I&#8217;ve updated KFM to use HTML5&#8217;s multiple-file input box where possible.</p>
<p>To do this, first create the element:</p>

  var input=document.createElement('input');
  input.type='file'; // use old-style JavaScript method to make sure all browsers respect it
  input.name='kfm_file';

<p>Notice [...]]]></description>
			<content:encoded><![CDATA[<p>As a response to a reported bug where <a href="http://code.google.com/p/kfm/issues/detail?id=37">Chrome was taking ages</a> to load up a flash multiple-file uploader, I&#8217;ve updated KFM to use HTML5&#8217;s multiple-file input box where possible.</p>
<p>To do this, first create the element:</p>
<pre class="javascript">
  var input=document.createElement('input');
  input.type='file'; // use old-style JavaScript method to make sure all browsers respect it
  input.name='kfm_file';
</pre>
<p>Notice that we&#8217;re not using <code>setAttribute</code> to set the type and name &#8211; that&#8217;s a DOM method which works in most browsers but not (of course&#8230;) in Internet Explorer 6, where it has bugs.</p>
<p>And now, we tell the input to use the multiple-upload method. We use <code>.setAttribute</code> in this case because we only expect newer browsers to succeed with it.</p>
<pre class="javascript">
  input.setAttribute('multiple','multiple');
  if(input.multiple)input.name='kfm_file[]';
</pre>
<p>In the second line, we check to see if the element is now marked as a multiple-uploader (most current browsers will not succeed in this), and if it does, then rename the input element by adding a <code>[]</code> to the end. If this is not done, then the server will only see the first file which is uploaded.</p>
<p>That&#8217;s the client-side done. This will only be visible in newer browsers such as Chrome, Safari 4, Firefox 3.6. I expect Internet Explorer will eventually catch up by 2020 or so.</p>
<p>If you&#8217;re doing this in pure HTML, then I suppose this would be good enough for you:</p>
<pre>
&lt;input type="file" multiple="multiple" name="file[]" /&gt;
</pre>
<p>In this case, you must put the <code>[]</code> in the name in all cases.</p>
<p>On the server-side, you need to write your upload receiver to expect either a single element, or an array.</p>
<p>For some really goddamned stupid reason, when multiple files are uploaded to PHP, the results are interlaced in a really crappy and awkward manner (I don&#8217;t like it).</p>
<p>Instead of something logical and easy to use, like this:</p>
<pre class="php">
array(
  [0] => array(
    'name' =&gt; 'file1.txt',
    'tmp_name' =&gt; '/tmp/abcdef'
    ....
  ),
  [1] => array(
    'name' =&gt; 'file2.txt',
    'tmp_name' =&gt; '/tmp/ghijkl'
    ....
  )
);
</pre>
<p>You get this&#8230;</p>
<pre>
array(
  'name' =&gt; array(
    [0] =&gt; 'file1.txt',
    [1] =&gt; 'file2.txt'
  ),
  'tmp_name' =&gt; array(
    [0] =&gt; '/tmp/abcdef',
    [1] =&gt; '/tmp/ghijkl'
  ),
  ...
);
</pre>
<p>While that looks at first glance to be easy to use, it&#8217;s not. You can&#8217;t do a simple &#8220;<code>foreach($_FILES['kfm_file'] as $file)</code>&#8221; and expect the above to be usable at all&#8230;</p>
<p>So, the first thing I do, is to check for the $_FILES['kfm_file'], and convert it into the first form above, which is very easy to work with:</p>
<pre class="php">
$files=array();
$fdata=$_FILES['kfm_file'];
if(is_array($fdata['name'])){
 for($i=0;$i&lt;count($fdata['name']);++$i){
  $files[]=array(
   'name'    =&gt;$fdata['name'][$i],
   'tmp_name'=&gt;$fdata['tmp_name'][$i],
  );
 }
}
else $files[]=$fdata;
</pre>
<p>In my own case, I&#8217;m only interested in the name and tmp_name variables, so that&#8217;s all I set up.</p>
<p>Now you can do a <code>foreach</code> on <code>$files</code> and treat them all individually.</p>
<pre class="php">
foreach($files as $file){
  // uploaded location of file is $file['tmp_name']
  // original filename of file is $file['file']
}
</pre>
<p>If you want to see this in KFM, have a look at the <a href="http://kfm.verens.com/demo/trunk/index.php?lang=en">nightly-updated demo</a> tomorrow, or <a href="http://code.google.com/p/kfm/source/checkout">download from SVN</a> right now.</p>
<p>oh &#8211; and <a href="http://www.amazon.co.uk/JQuery-1-3-PHP-Kae-Verens/dp/1847196985">buy my book!</a></p>
]]></content:encoded>
			<wfw:commentRss>http://verens.com/archives/2009/12/28/multiple-file-uploads-using-html5/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>kfm2: example widget</title>
		<link>http://verens.com/archives/2009/10/18/kfm2-example-widget/</link>
		<comments>http://verens.com/archives/2009/10/18/kfm2-example-widget/#comments</comments>
		<pubDate>Sun, 18 Oct 2009 20:19:50 +0000</pubDate>
		<dc:creator>Kae Verens</dc:creator>
				<category><![CDATA[ajax]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[kfm]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://verens.com/?p=868</guid>
		<description><![CDATA[<p>As an example of a front-end widget, I&#8217;ve whipped up a demo of file-tree navigation using the excellent jsTree widget.</p>
<p>here is the demo</p>
<p>You can see from the source how short it is &#8211; all it does is load up the jsTree library (and jQuery), then it connects directly to KFM2 to get data about the [...]]]></description>
			<content:encoded><![CDATA[<p>As an example of a front-end widget, I&#8217;ve whipped up a demo of file-tree navigation using the excellent <a href="http://www.jstree.com/">jsTree</a> widget.</p>
<p><a href="http://verens.com/demos/kfm2/widgets/demos/jstree.html">here is the demo</a></p>
<p>You can see from the source how short it is &#8211; all it does is load up the jsTree library (and jQuery), then it connects directly to KFM2 to get data about the files on the server.</p>
<p>in fact&#8230; it&#8217;s so short I&#8217;ll just paste the demo into this page as well:<br />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script><br />
<script src="/demos/kfm2/widgets/jstree/jquery.tree.min.js"></script><br />
<script>
$(document).ready(function () { 
	$("#tree_div").tree({
		data : { 
			type : "json",
			async : true,
			opts : {
				async : true,
				method : "POST",
				url : "/demos/kfm2/trunk/?p=get_file_listing" // KFM LOCATION
			}
		},
		callback : { 
			'beforedata':function(node){
				var id=$(node).attr('id');
				if(!id)return {'d':'/'};
				return {'d':$(node).attr('id').replace(/^kfm2_node_/,'')};
			},
			'ondata':function(res){
				var data=[],i;
				for(i in res.files)data.push({'data':i,'attributes':{'id':'kfm2_node_'+res.d+'/'+i}});
				for(i in res.directories)data.push({'data':i,'state':'closed','attributes':{'id':'kfm2_node_'+res.d+'/'+i}});
				return data;
			}
		}
	});
});
</script></p>
<div id="tree_div"></div>
<p style="clear:left">You should see a list of files just above this paragraph.</p>
<p>No modification of jsTree was necessary, as it handily gives two event triggers which can be used to translate the request data to KFM&#8217;s request format, and the received data back into jsTree&#8217;s data format.</p>
<p>Here is the code used to attach the tree to the #tree_div element in this page:</p>
<pre class="javascript">
$("#tree_div").tree({
	data : {
		type : "json",
		async : true,
		opts : {
			async : true,
			method : "POST",
			<span style="font-weight:bold">url : "/demos/kfm2/trunk/?p=get_file_listing" // KFM LOCATION</span>
		}
	},
	callback : {
		<span style="font-weight:bold">'beforedata':function(node)</span>{
			var id=$(node).attr('id');
			if(!id)return {'d':'/'};
			return {'d':$(node).attr('id').replace(/^kfm2_node_/,'')};
		},
		<span style="font-weight:bold">'ondata':function(res)</span>{
			var data=[],i;
			for(i in res.files)data.push({'data':i,'attributes':{'id':'kfm2_node_'+res.d+'/'+i}});
			for(i in res.directories)data.push({'data':i,'state':'closed','attributes':{'id':'kfm2_node_'+res.d+'/'+i}});
			return data;
		}
	}
});
</pre>
<p>This is just an example of what can be built quickly with the new RPC-based KFM.</p>
<p>Further and more useful examples will come soon.</p>
]]></content:encoded>
			<wfw:commentRss>http://verens.com/archives/2009/10/18/kfm2-example-widget/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>kfm2: plugin management</title>
		<link>http://verens.com/archives/2009/10/18/kfm2-plugin-management/</link>
		<comments>http://verens.com/archives/2009/10/18/kfm2-plugin-management/#comments</comments>
		<pubDate>Sun, 18 Oct 2009 15:04:11 +0000</pubDate>
		<dc:creator>Kae Verens</dc:creator>
				<category><![CDATA[kfm]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://verens.com/?p=862</guid>
		<description><![CDATA[<p>I know, I promised this last week &#8211; I&#8217;m afraid I&#8217;ve been up to my eyes in work and just exhausted at home, so all I can do is apologise.</p>
<p>Anyway, I&#8217;ve put together the basics enough that there is one single plugin, which gets a directory listing, and echoes it to the screen in JSON.</p>
<p>You [...]]]></description>
			<content:encoded><![CDATA[<p>I know, I promised this last week &#8211; I&#8217;m afraid I&#8217;ve been up to my eyes in work and just exhausted at home, so all I can do is apologise.</p>
<p>Anyway, I&#8217;ve put together the basics enough that there is one single plugin, which gets a directory listing, and echoes it to the screen in JSON.</p>
<p>You can get a copy of the basics using the following SVN command:</p>
<pre class="bash">svn checkout http://kfm.googlecode.com/svn/kfm2/ kfm2</pre>
<p>In that, there are two directories &#8211; <code>trunk</code> and <code>plugins</code>. The <code>trunk</code> is what will become the new KFM core, and the items in <code>plugins</code> will be server-side plugins that can be used by copying them into <code>trunk/plugins/</code> (or do as I do and <code>ln -s ../../plugins/*</code> from the <code>trunk/plugins/</code> to create symlinks).</p>
<p>When you load up KFM2 initially, it will do an extremely basic install, with no plugins enabled. Follow the instructions on-screen to get set up.</p>
<p>The <code>config.php</code> contains just two items at the moment. I want to keep this as absolutely clean as possible, so the items in there are the only essentials &#8211; all other configuration will be done using KFM&#8217;s admin section.</p>
<ul>
<li><code>KFM_USERDIR</code> &#8211; this is the directory that is to be managed by KFM. Just like KFM1, a directory called <code>.files</code> will be created in there that holds config stuff, such as the list of enabled plugins, etc.</li>
<li><code>KFM_ADMIN_PASSWORD</code> &#8211; this password allows access to KFM&#8217;s admin section, where you can currently just enable/disable plugins. By default, it is blank, and you will need to change it before you can access the admin section.</li>
</ul>
<p>There is no JavaScript yet in this, so it&#8217;s tricky to see exactly what it&#8217;s supposed to do.</p>
<p>I&#8217;ve set up a basic demo <a href="http://verens.com/demos/kfm2/trunk/">here</a>, but loading that directly will just get you a login screen.</p>
<p>KFM2 is designed to be interacted with purely through RPC (except for configuration which requires browser access). The demo has the first plugin, &#8220;get_file_listing&#8221; enabled, which we can use to see what happens.</p>
<p><a href="http://verens.com/demos/kfm2/trunk/?p=get_file_listing">/?p=get_file_listing</a> &#8211; this example calls KFM2 and tells it to run the <code>get_file_listing</code> plugin. by default, it will return the root directory of your KFM_USERDIR in JSON format:</p>
<pre>
{
  "d":"",
  "files":{
    "file2":{
      "size":0,
      "mtime":1255875795
    },
    "file1":{
      "size":0,
      "mtime":1255875794
    },
    "file3":{
      "size":0,
      "mtime":1255875796
    }
  },
  "directories":{
    "dir1":{
      "mtime":1255875809
    }
  }
}
</pre>
<p>The <code>d</code> parameter there is the directory that was requested (by default, it&#8217;s blank), which is internally added to the KFM_USERDIR to get the actual local directory.</p>
<p>The results returned are separated into two arrays, of files and directories. My guess is that most required uses on the client-side will be specific to either directories or files, so this saves you having to separate them yourself.</p>
<p>Changing the requested directory is simple &#8211; just add a <code>d</code> parameter to the request URL:</p>
<p><a href="http://verens.com/demos/kfm2/trunk/?p=get_file_listing&#038;d=dir1">/?p=get_file_listing</a> &#8211; this example requests the contents of <code>/dir1</code>.</p>
<h2>How to write your own plugin</h2>
<p>The system as it is will let you write plugins that handle most of the things that you might want to do &#8211; upload files, create/move/delete files or directories, download files, etc.</p>
<p>I&#8217;ll get around to writing these anyway, but if you feel like writing them, then feel free! Just copy how the <code>get_file_listing</code> plugin works.</p>
<p>So, here&#8217;s how a basic plugin works.</p>
<p>In KFM2&#8217;s plugin&#8217;s directory, create a directory named after the plugin. Please use just lowercase letters and underscores. Examples: &#8220;upload&#8221;, &#8220;get_file&#8221;, &#8220;rename_file&#8221;, &#8220;zip_directory&#8221;, etc.</p>
<p>In that directory, create a <code>plugin.php</code> file, which describes the plugin:</p>
<pre class="php">
&lt;?php
$plugin=array(
  'name'=&gt;'Get File Listing',
  'description'=&gt;'Retrieves a list of files and directories within a given directory',
  'version'=&gt;0
);
</pre>
<p>Use an integer for the version number. It will probably never need to be used, but if it is, it is easier to compare two integers than two of the usual <code>x.y.z</code> version numbers.</p>
<p>When you log into your admin area, you&#8217;ll see the details above shown in your plugin management module.</p>
<p>For most plugin cases, you will also need a file named after the plugin itself. Until the events code is written, this is all cases.</p>
<p>In our example, we create a file named <code>plugins/get_file_listing/get_file_listing.php</code>. It should contain a function also named after the plugin:</p>
<pre class="php">
function get_file_listing(){
  // place plugin code here
}
</pre>
<p>In the URL above, I had <code>/?p=get_file_listing</code> &#8211; what KFM then did was to load up the <code>get_file_listing/get_file_listing.php</code> file and run <code>get_file_listing()</code>. That function then used whatever other things were mentioned in the <code>$_REQUEST</code> array to carry out its work.</p>
<p>That&#8217;s pretty much it for now. That should be enough to create most basic plugins.</p>
<p>For the next KFM article, I&#8217;ll write up another server-side plugin, and will add in some client-side code so you can see how it would actually be used in a real project. It will demonstrate how JavaScript and KFM will talk to each other.</p>
<p>If anyone writes up any plugins that they want included in the SVN download, please email them to me (kae@verens.com).</p>
<h2>Requested plugins</h2>
<p>Here&#8217;s the list of plugins that have already been identified as needing to be written.</p>
<p>Server-side plugins that can be written right now:</p>
<ul>
<li>file upload</li>
<li>delete file / directory</li>
<li>rename file / directory (also counts as &#8220;move&#8221;)</li>
<li>download file</li>
<li>create zip of directory</li>
<li>unzip a zip file</li>
<li>manipulate an online image</li>
</ul>
<p>Plugins that require more work in the core:</p>
<ul>
<li>connect to remote file-systems (FTP, NFS, other KFMs, etc)</li>
<li>user-based security</li>
<li>different KFM_USERDIR based on the logged-in user, or even the site&#8217;s hostname</li>
<li>plugin to resize images that were uploaded so they&#8217;re kept to a certain max size</li>
<li>quotas (can /probably/ be done at the moment&#8230; but not sure)</li>
<li>databases</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://verens.com/archives/2009/10/18/kfm2-plugin-management/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>KFM2 has begun. requesting ideas of sample plugins to develop</title>
		<link>http://verens.com/archives/2009/10/04/kfm2-has-begun-requesting-ideas-of-sample-plugins-to-develop/</link>
		<comments>http://verens.com/archives/2009/10/04/kfm2-has-begun-requesting-ideas-of-sample-plugins-to-develop/#comments</comments>
		<pubDate>Sun, 04 Oct 2009 20:24:08 +0000</pubDate>
		<dc:creator>Kae Verens</dc:creator>
				<category><![CDATA[ajax]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[kfm]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://verens.com/?p=858</guid>
		<description><![CDATA[<p>As ye all know now, KFM1.x is finished. I&#8217;m not interested in struggling with it anymore. I&#8217;ve started a new project which will exceed KFM1.x&#8217;s capabilities.</p>
<p>The main problem with 1.x was that it was monolithic &#8211; there was one single codebase, which encompassed both the server-side and the client-side. The client-side code was useless without [...]]]></description>
			<content:encoded><![CDATA[<p>As ye all know now, KFM1.x is finished. I&#8217;m not interested in struggling with it anymore. I&#8217;ve started a new project which will exceed KFM1.x&#8217;s capabilities.</p>
<p>The main problem with 1.x was that it was monolithic &#8211; there was one single codebase, which encompassed both the server-side and the client-side. The client-side code was useless without the server-side, and the server-side code had hooks specifically designed to be used by the client-side.</p>
<p>While it was <i>possible</i> to build a different client-side GUI that would hook into the server-side, it would be a large undertaking, and would involve changing a lot of the PHP &#8211; especially as the PHP wrote the &#8220;boot&#8221; JavaScript in the first place&#8230;</p>
<p>KFM2 is designed from the beginning to have a different architecture based specifically on plugins. The core code is a small plugin manager (mostly written already), written in PHP, but it will not be necessary that the client-side is in JavaScript &#8211; or even that there is any interaction with a browser at all!</p>
<p>The idea is this &#8211; if you want to do something incredibly simple, such as select an existing directory that will be used in your CMS to create an image gallery out-of (let&#8217;s say you need to choose from a number of existing directories full of images), then it is a total waste of bandwidth and CPU to load up a full-on file-manager.</p>
<p>In this case, and it&#8217;s the first I&#8217;ll be building to show how all this works, what should happen is that the browser will show something simple like this:</p>
<table>
<tr>
<th>Choose the image directory</th>
<td>
<input type="button" value="Choose..." /></td>
</tr>
</table>
<p>&#8230;and when that&#8217;s clicked, a small popup will appear which lets you choose the directory you want, in a tree-like manner &#8211; you open the branches until you find the one you want, then you click it. Afterwards, the form will change:</p>
<table>
<tr>
<th>Choose the image directory</th>
<td>
<input type="button" value="Choose..." /> <code>/images/the-lads-2009/</code> selected</td>
</tr>
</table>
<p>From the technical point of view, there&#8217;re a few things to explain about how this would be done.</p>
<p>jQuery would be used to attach an event to the button which would popup the selection window. This selection window will use Ajax to speak with the KFM2 server and retrieve the list of directories, one level at a time as the branches are expanded. When one is selected, a hidden input will be set to the name of the directory.</p>
<p>This sounds incredibly simple, and it is. What&#8217;s important, though, is that <i>no-one is doing this at the moment!</i>. Right now, if you go search for existing plugins to do this kind of thing, you&#8217;ll find either small widgets with both the server and client-side code ready for you, or full-on applications (such as KFM1.x) which can do the job, but which are overkill.</p>
<p>The problem with the applications is obvious &#8211; too much stuff going on, making it slow and cumbersome.</p>
<p>The problem with the small widgets is that each one is complete in itself, and therefore a lot of the functionality is repeated. This is a bad idea &#8211; what if you need to make a site-wide change? You&#8217;d need to go through every widget and change it!</p>
<p>What I&#8217;m proposing to make of KFM2 is that it will mostly be a server-side application, but which has a nice easy-to-use API which can be hooked into by lots of different jQuery widgets (or Mootools, or whatever you want, really &#8211; write it in Python or Delphi if you want&#8230;).</p>
<p>So, my first widget will be the one described above &#8211; a directory selector.</p>
<p>I&#8217;d like to know what other things people need to do with files online, which are simple and they&#8217;d prefer not to have to load a whole file-manager to do.</p>
<p>I&#8217;ll release the first widget and a demo of it some time over the next week. I intend to write a whole load of widgets, culminating in a full-on GUI similar to the present KFM1.x one, all hooking into the new engine.</p>
]]></content:encoded>
			<wfw:commentRss>http://verens.com/archives/2009/10/04/kfm2-has-begun-requesting-ideas-of-sample-plugins-to-develop/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>KFM 1.4.2 released. now with CKeditor support</title>
		<link>http://verens.com/archives/2009/10/04/kfm-1-4-2-released-now-with-ckeditor-support/</link>
		<comments>http://verens.com/archives/2009/10/04/kfm-1-4-2-released-now-with-ckeditor-support/#comments</comments>
		<pubDate>Sun, 04 Oct 2009 09:36:44 +0000</pubDate>
		<dc:creator>Kae Verens</dc:creator>
				<category><![CDATA[ajax]]></category>
		<category><![CDATA[fckeditor]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[kfm]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://verens.com/?p=852</guid>
		<description><![CDATA[<p>
<p>KFM 1.4.2 has been released. It&#8217;s a minor maintenance release, but it adds support for CKeditor. TinyMCE and FCKeditor have been checked as well.</p>
<p>demo using CKeditor</p>
<p>This release also adds a configurable restriction, where images larger than a certain resolution will simply not be allowed in the repository.</p>
<p>Very large images can cause servers to crash when [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://kfm.verens.com/"><img src="http://verens.com/wp-content/uploads/2009/10/kfm-300x174.jpg" alt="kfm" title="kfm" width="300" height="174" class="alignleft size-medium wp-image-856" /></a>
<p>KFM 1.4.2 has been released. It&#8217;s a minor maintenance release, but it adds support for <a href="http://ckeditor.com/">CKeditor</a>. <a href="http://tinymce.moxiecode.com/">TinyMCE</a> and FCKeditor have been checked as well.</p>
<p><a href="http://kfm.verens.com/Documentation/Installation/Using-KFM-as-a-plugin-for-CKeditor">demo using CKeditor</a></p>
<p>This release also adds a configurable restriction, where images larger than a certain resolution will simply not be allowed in the repository.</p>
<p>Very large images can cause servers to crash when the system tries to generate thumbnails, because of the large amount of RAM needed. For example, a 3000&#215;2000 image will use up at least 24MB just to hold the thing in memory, and much more to handle the manipulation. 24MB is a large amount of RAM to a web app.</p>
<p>There are also some code additions which are not used by the KFM GUI, but can be used by tools that hook into the KFM engine. These allow uploaded files to be placed in directories specified at the time of upload, or to replace existing files, or even to take an uploaded image and apply HSL transformations to it (when <a href="http://www.imagemagick.org/script/index.php">ImageMagick</a> is installed). These are not documented, but anyone that needs this functionality will be a good enough programmer to read the source and find it (or email me <img src='http://verens.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />  ).</p>
<p><a href="http://code.google.com/p/kfm/downloads/list">Download KFM 1.4.2 here</a></p>
]]></content:encoded>
			<wfw:commentRss>http://verens.com/archives/2009/10/04/kfm-1-4-2-released-now-with-ckeditor-support/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>KFM2: the beginning</title>
		<link>http://verens.com/archives/2009/09/30/kfm2-the-beginning/</link>
		<comments>http://verens.com/archives/2009/09/30/kfm2-the-beginning/#comments</comments>
		<pubDate>Wed, 30 Sep 2009 22:11:30 +0000</pubDate>
		<dc:creator>Kae Verens</dc:creator>
				<category><![CDATA[ajax]]></category>
		<category><![CDATA[databases]]></category>
		<category><![CDATA[fckeditor]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[kfm]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[web development]]></category>
		<category><![CDATA[webme]]></category>

		<guid isPermaLink="false">http://verens.com/?p=847</guid>
		<description><![CDATA[<p>KFM 1.x has reached the end of its development. It has fulfilled its original purpose; to improve on the default file-manager for FCKeditor, and well-exceeded it.</p>
<p>From my records, I can see that KFM has been installed on over 9000 separate domains. That is quite a lot of sites, and says quite loudly how important it [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://kfm.verens.com/">KFM 1.x</a> has reached the end of its development. It has fulfilled its original purpose; to improve on the default file-manager for <a href="http://fckeditor.net/">FCKeditor</a>, and well-exceeded it.</p>
<p>From my records, I can see that KFM has been installed on over 9000 separate domains. That is quite a lot of sites, and says quite loudly how important it is that KFM2 is at least as good as KFM1 (we all know about the KDE4.0 fiasco&#8230;).</p>
<p>KFM2 will blow KFM1 well out of the water. It will do everything that KFM1 does, but much quicker, and with a much less monolithic architecture, allowing it to be hugely flexible. I am planning on creating a <a href="http://jqueryui.com/download">download section similar to jQuery UI&#8217;s</a>, where you can choose the components that you want in the system, and it will be built up and configured for you, ready for download.</p>
<p>See, KFM 2 will be modular. If you just want a simple upload/download facility, then you will only need the core, and plugins to handle uploads and downloads. If you want the whole shebang, you will find plugins for various ways of selecting files and directories, full-on graphical UIs such as the existing KFM1 forces on the user, plugins for hooking into external file systems using FTP or whatever other method people can imagine, plugins for multi-media, file editing, databases, user authentication, search, RSS, and so on.</p>
<p>Basically everything that KFM1 already does, but with the option to easily remove/add bits that you want. Make it as fast or as &#8220;bling&#8221; as you want.</p>
<p>KFM2 will have a number of new things which are not available in any other online file-systems, that I know of.</p>
<h3>new file-system things</h3>
<p>The file system will be modular. You will be able to attach symbolic links to any part of the file system, linking to other external systems.</p>
<p>As an example, let&#8217;s look at a URL: <code>http://example.com/kfm/get/images/site1/logo.jpg</code>.</p>
<p>One of the new ideas is that this will not necessarily be located on the server named <code>example.com</code>.</p>
<p>If you are running a very busy website, you might prefer to delegate image management to a different machine deeper in your network, so you add a symbolic link <code>/images/</code> linking to the image-management machine. This causes the server to issue a redirect to the browser, redirecting it to <code>http://images.example.com/kfm/get/site1/logo.jpg</code>.</p>
<p>Now, imagine that the image management server doesn&#8217;t host the logo.jpg file on itself. Maybe it&#8217;s one of a number of <code>images.example.com</code> servers in a load-balancing cluster, and the file is actually located on a file-server accessible only by FTP. So, we add a symbolic link in the server&#8217;s KFM, telling it how to connect to the FTP server. The image server does this, gets the required file, and sends it to the browser.</p>
<p>This sounds a bit complex, but at least it&#8217;s possible with the new system. The old system simply would not be able to handle that at all.</p>
<h3>API</h3>
<p>At the moment, if you want to select a file or directory, you fire up KFM1, wait 15 seconds for it to finish booting itself up, and select the file or directory. That&#8217;s way too long. Really, you should only need to load up a tiny widget that&#8217;s designed specifically for picking a file.</p>
<p>The new system will have a simple core with an API that can be connected to by little JavaScript widgets. As an example, let&#8217;s say you just want to get the file-listing for the <code>foo</code> directory.</p>
<p>At the moment, you need to go through the whole business of booting up KFM&#8217;s GUI, navigating to the right directory, then waiting for the server to connect to the database, generate thumbnails and other unnecessary stuff.</p>
<p>You should just have to do something simple like load up <code>http://example.com/kfm/rpc.php?a=get_file_listing&amp;v=/foo</code> through jQuery&#8217;s <code>$.get()</code> function. The RPC script does exactly what was asked, and nothing more.</p>
<p>This should allow us to write some incredibly fast and tiny scripts for all the file manipulation things you could possibly want.</p>
<p>Think of it as the &#8220;gnu&#8221; way of doing KFM &#8211; many small tools, each of which is designed to do one task well.</p>
<p>Of course, you will still be able to use the original GUI with this, after it&#8217;s been re-engineered to hook into the new RPC system.</p>
<p>Or, you can write your own &#8211; the RPC&#8217;s API will be well-documented, and will use simple HTTP parameters, so you can write your widgets in whatever language you want &#8211; JavaScript is what I will be writing in, but there&#8217;s no reason why you&#8217;re confined to that &#8211; write a GUI in Python, C, Flash &#8211; whatever you&#8217;re comfortable with.</p>
<h3>plugins</h3>
<p>I think the new plugin architecture will make this profoundly extensible. I&#8217;m writing the core to be as flexible and stable as possible. You will be able to write a plugin to just about anything:</p>
<ul>
<li>authenticate a user before serving a file.</li>
<li>change a user&#8217;s root directory based on the server-name or the user&#8217;s authentication.</li>
<li>the entire system is held on a different machine accessible only by FTP? fine &#8211; let&#8217;s change how files are accessed.</li>
<li>record all files and directories in a database, allowing searches to be done.</li>
<li>manipulate files online &#8211; edit text files, rotate or crop or resize images, move or rename or delete, etc. standard KFM1 stuff, these.</li>
<li>create a log plugin, so all access is recorded.</li>
<li>create a quota plugin, for denying uploads or downloads when the quota is exceeded.</li>
</ul>
<p>It was possible for us (Benjamin and myself) to write all of these into KFM1, but as we are only two people, and very busy people at that, it&#8217;s never been the absolute top priority to get all these things done.</p>
<p>But, when KFM2 is released, you won&#8217;t have to wait for us anymore. You will be able to write plugins, or download plugins created by other people, which do all of the above and I&#8217;m sure there will be plugins that I simply have not imagined yet, that inventive people will come up with (Conor, I&#8217;m sure you&#8217;ll be one of those!)</p>
<h3>languages</h3>
<p>Languages have always been one of the cool things about KFM. Version 1.3 was released in about 13 languages in total. Unfortunately, the code got too complex in 1.4 to easily add more, but KFM2 is starting from scratch with the learning-curve of KFM1 well behind me. I&#8217;ve already made most of the big mistakes I&#8217;m likely to make, so from now on, things should be much easier.</p>
<p>How languages will work is that a website will be created which allows people to help out open-source projects, <em>not just KFM</em> by providing translations of words and sentences.</p>
<p>The programmer will create a screen-shot showing the text in use, and will provide the untranslated text in a format such as .po. Translators will translate the text on-line, and the translation will be available to download by the programmer as soon as it&#8217;s done.</p>
<p>To ensure good translation, each line will be presented to a number of different translators. The translations which agree the most with each other, will be considered the &#8220;right&#8221; one.</p>
<p>Using this, it will be possible for KFM to organically add languages with no interaction from myself or any other programmers. When first loaded, a plugin would try to translate messages into the user&#8217;s language. Finding that it doesn&#8217;t have the language in its database, it will try downloading it from the language translation website. If it&#8217;s not available, a request will be added that it be created. When translators that speak that language come to the website, they will be automatically given the KFM text to translate to that language. The next time the plugin checks, the translation might be done, and it will be added to the KFM instance&#8217;s local language database.</p>
<p>Of course, people don&#8217;t just do this stuff for the hell of it. It&#8217;s more fun if there&#8217;s a competition or reward. It would be nice if I could get a few paying customers to add their own translation requests to the website &#8211; that way I could offer a reward to the best translators (those that do the most work, or are the most consistent).</p>
<p>The competition aspect comes in, where you give people points for every translation they do that is matched by someone else&#8217;s translation of the same text.</p>
<p>Google does a similar thing, for example, where it shows images to people and asks them to come up with keywords describing the image &#8211; the commonest keywords are considered to be correct. Same trick, different target.</p>
<p>Anyway! Without further ado, I have a core to design, and tests to create. I was going to talk about testing with PHPUnit, automatic upgrades, and the like, but to hell with ye all &#8211; I&#8217;ve work to do <img src='http://verens.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://verens.com/archives/2009/09/30/kfm2-the-beginning/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>KFM 1.4 released</title>
		<link>http://verens.com/archives/2009/09/27/kfm-1-4-released/</link>
		<comments>http://verens.com/archives/2009/09/27/kfm-1-4-released/#comments</comments>
		<pubDate>Sun, 27 Sep 2009 11:27:44 +0000</pubDate>
		<dc:creator>Kae Verens</dc:creator>
				<category><![CDATA[ajax]]></category>
		<category><![CDATA[book]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[kfm]]></category>
		<category><![CDATA[packt]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://verens.com/?p=840</guid>
		<description><![CDATA[<p>It&#8217;s been almost a full year since the last release, 1.3.1, and I haven&#8217;t done much on KFM in that time.</p>
<p>Benjamin ter Kuile, though, has! Today, we release KFM 1.4</p>
<p>In the time that I&#8217;ve been busy with other stuff, and procrastinating on KFM, Benjamin has been working diligently, adding features and making the core files [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been almost a full year since the <a href="http://kfm.verens.com/ww.phpBB3/viewtopic.php?f=5&#038;t=292">last release, 1.3.1</a>, and I haven&#8217;t done much on KFM in that time.</p>
<p>Benjamin ter Kuile, though, has! Today, we release <a href="http://kfm.verens.com/ww.phpBB3/viewtopic.php?f=5&#038;t=419">KFM 1.4</a></p>
<p>In the time that I&#8217;ve been busy with other stuff, and procrastinating on KFM, Benjamin has been working diligently, adding features and making the core files more stable.</p>
<p>Here is a short list of improvements, gleaned from the SVN logs over the last year. I&#8217;m sure I&#8217;m missing a lot.</p>
<ul>
<li>jQuery upgraded to 1.3.2 (faster, better, stronger)</li>
<li>you can edit multiple text files simultaneously</li>
<li>context menu code improved to help it work in Chrome, Opera and Safari</li>
<li>file icons are now created as a montage, improving display speed</li>
<li>a lot of functions converted to &#8220;lazyload&#8221; &#8211; improves startup speed</li>
<li>images are also lazyloaded &#8211; if an icon is not visible on the screen, its thumbnail is not loaded</li>
<li>lots of bug-fixes</li>
</ul>
<p>Not many new features, as KFM was basically complete.</p>
<p>1.4 is the <em>last</em> 1.x version which will be released. We&#8217;re done with the code-base, and ready to start on a much more ambitious project.</p>
<p>We&#8217;re going to rebuilt the entire system from scratch in a modular way, adding functionality that would be very difficult to shoehorn into the present system. The new version will be called KFM 2, and I&#8217;m really excited about it. I will be starting the coding for it very soon, as soon as I&#8217;ve finished with the release of my book, <a href="http://www.packtpub.com/jquery-1-3-with-php/book">jQuery 1.3 with PHP</a>.</p>
<p>For those of you that are already using 1.3; 1.4 is /faster/, but 1.3 already completes the initial spec, so only upgrade if you find that 1.3 is slow. New users should install 1.4.</p>
]]></content:encoded>
			<wfw:commentRss>http://verens.com/archives/2009/09/27/kfm-1-4-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>jQuery 1.3 With PHP: cover mockup</title>
		<link>http://verens.com/archives/2009/09/18/php-and-jquery-cover-mockup/</link>
		<comments>http://verens.com/archives/2009/09/18/php-and-jquery-cover-mockup/#comments</comments>
		<pubDate>Fri, 18 Sep 2009 11:01:37 +0000</pubDate>
		<dc:creator>Kae Verens</dc:creator>
				<category><![CDATA[book]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[kfm]]></category>
		<category><![CDATA[packt]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[web development]]></category>
		<category><![CDATA[webme]]></category>
		<category><![CDATA[webworks]]></category>

		<guid isPermaLink="false">http://verens.com/?p=830</guid>
		<description><![CDATA[<p></p>
<p>I&#8217;ve been sent a mockup for the book&#8217;s cover. The suggested title of the book is &#8220;jQuery 1.3 with PHP&#8221;. The working title was &#8220;PHP and jQuery&#8221;. Which do you prefer?</p>
<p>The book has been completed, in that all the chapters are written, and it&#8217;s in the final edit phase at the moment. This involves Packt [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://verens.com/wp-content/uploads/2009/09/6989_MockupCover.jpg"><img src="http://verens.com/wp-content/uploads/2009/09/6989_MockupCover-243x300.jpg" alt="6989_MockupCover" title="6989_MockupCover" width="243" height="300" class="alignleft size-medium wp-image-831" /></a></p>
<p>I&#8217;ve been sent a mockup for the book&#8217;s cover. The suggested title of the book is &#8220;jQuery 1.3 with PHP&#8221;. The working title was &#8220;PHP and jQuery&#8221;. Which do you prefer?</p>
<p>The book has been completed, in that all the chapters are written, and it&#8217;s in the final edit phase at the moment. This involves Packt having a technical editor try everything in the book just to iron out any kinks. It&#8217;s already been gone over by three other reviewers, and the only problem appears to have been with the File Management chapter, where the web-server was IIS on Windows. That should be solved by the time the book comes out.</p>
<p>I&#8217;ve learned a lot while writing this book. A major point that keeps raising its head is that I keep using colloquialisms and aphorisms (ha! &#8220;raising its head&#8221;), and those are not globally understood. Another is that I keep using British spelling, but it&#8217;s expected that most readers will be American.</p>
<p>From a coding point of view, I tend to write compact code with comments only appearing where something is obviously confusing, but I&#8217;ve tried to put proper comments in the book whenever any reviewer asked a question about the code.</p>
<p>Anyway &#8211; I expect it will be in PDF form in only a few weeks! I&#8217;m looking forward to hearing what people think of it.</p>
<p>On a funny note, I was working on something in <a href="http://webworks.ie/">work</a> recently, and was trying to figure the best way to do it, when I suddenly remembered I&#8217;d written a whole chapter on it, so went and read what I&#8217;d written! I&#8217;ll be keeping a copy of the book on my own shelf <img src='http://verens.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>This kind of thing is always happening to me &#8211; I would need to solve some problem (hooking an OKI B2200 printer to Linux over Samba, for example), go searching for the answer, and find that I&#8217;d written the solution for it a year or two previously&#8230;</p>
<p>By the way, <a href="http://kfm.verens.com/">KFM 1.4</a> will be released next week. It will be the last 1.x version. We (Benjamin and myself) are starting a total rewrite after that, which will become KFM 2. It&#8217;s going to be massive!</p>
<p><strong>EDIT: 2009-09-18</strong> Wow, that was quick! The book is already <a href="http://www.packtpub.com/jquery-1-3-with-php/book">available to pre-book</a></p>
]]></content:encoded>
			<wfw:commentRss>http://verens.com/archives/2009/09/18/php-and-jquery-cover-mockup/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>a tale of prefixes</title>
		<link>http://verens.com/archives/2009/08/04/a-tale-of-prefixes/</link>
		<comments>http://verens.com/archives/2009/08/04/a-tale-of-prefixes/#comments</comments>
		<pubDate>Tue, 04 Aug 2009 08:56:23 +0000</pubDate>
		<dc:creator>Kae Verens</dc:creator>
				<category><![CDATA[databases]]></category>
		<category><![CDATA[kfm]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[web development]]></category>
		<category><![CDATA[webme]]></category>

		<guid isPermaLink="false">http://verens.com/?p=796</guid>
		<description><![CDATA[<p>I debugged a problem for a friend of mine over the last day. He had installed bbPress on a server which also had WordPress on it, and his WordPress site just suddenly stopped serving comments and pages, and started killing the database server instead.</p>
<p>In the end (after a day of considering this and that and [...]]]></description>
			<content:encoded><![CDATA[<p>I debugged a problem for a friend of mine over the last day. He had installed <a href="http://bbpress.org/">bbPress</a> on a server which also had <a href="http://wordpress.org/">WordPress</a> on it, and his WordPress site just suddenly stopped serving comments and pages, and started killing the database server instead.</p>
<p>In the end (after a day of considering this and that and a lot of head-scratching), it turns out that the bbPress installation had been done using the same table prefix as the WordPress one.</p>
<p>See, when a web app is installed, it usually installs a load of database tables. The way to avoid these tables overwriting each other is to &#8220;namespace&#8221; them. The most common method is to simply place a unique prefix in front of the table names.</p>
<p>For example, WordPress and bbPress both have tables for posts. The default installation is to name them <strong>wp_</strong>posts and <strong>bb_</strong>posts, respectively, using wp_ and bb_ as prefixes. <a href="http://kfm.verens.com/">KFM</a> does that as well, using kfm_ by default.</p>
<p>In the current case, what happened is that the bbPress installation was done using wp_ as the prefix, and some of the WordPress tables were then changed to match what bbPress expected.</p>
<p>In the case of wp_posts, the field post_status was changed from a varchar holding values such as &#8220;publish&#8221; or &#8220;draft&#8221;, to a smallint holding just &#8216;1&#8242; or &#8216;0&#8242;. This had the immediate effect of unpublishing over 6000 articles on the blog. (aside: oi, WordPress &#8211; why are you not using enums?)</p>
<p>A few hours, spread over a day or so, were spent figuring that out then fixing that.</p>
<p>So, what actually happened? Why was wp_ used as the prefix?</p>
<p>Let&#8217;s look at the WordPress installation.</p>
<p><a href="http://verens.com/wp-content/uploads/2009/08/wordpress.jpg"><img src="http://verens.com/wp-content/uploads/2009/08/wordpress.jpg" alt="wordpress" title="wordpress" width="243" height="153" class="aligncenter size-full wp-image-797" /></a></p>
<p>When you install a copy of WordPress, the first thing you do is fill in the database details. This is the field for the prefix:</p>
<pre>&lt;input id="prefix" type="text" size="25" value="wp_" name="prefix"/&gt;</pre>
<p>Notice the name, &#8220;prefix&#8221;. A lot of browsers these days include auto-fill, which is sometimes useful. When encountering a form, the browser would fill in the details that it already knows, such as email address, etc.</p>
<p>The problem, though, is that sometimes, autofill might fill in details that really should be left blank or at their default states. An example of this is in <a href="http://www.phpbb.com/">phpBB</a>, the popular forum software &#8211; whenever an admin goes to edit a user&#8217;s details, autofill in Firefox tends to fill in the &#8220;password&#8221; field in the user form, but it really shouldn&#8217;t do that, and can potentially break a user&#8217;s account.</p>
<p>This is actually quite easy to fix, though, in the installer &#8211; the installation program just needs to change to use a different name for its input box:</p>
<pre>&lt;input id="prefix" type="text" size="25" value="wp_" name="<strong>wp_</strong>prefix"/&gt;</pre>
<p>Now the value should only be autofilled by values recorded from other WordPress installations, and should not affect future installations of other software.</p>
<p>The thing is, this is not what broke the system I was fixing.</p>
<p>Let&#8217;s look at the bbPress installation.</p>
<p><a href="http://verens.com/wp-content/uploads/2009/08/bbpress.jpg"><img src="http://verens.com/wp-content/uploads/2009/08/bbpress.jpg" alt="bbpress" title="bbpress" width="300" height="133" class="aligncenter size-full wp-image-798" /></a></p>
<p>When writing bbPress, more thought appears to have gone into the installation. The only fields visible here are database name, user, and password. These are the most commonly changed details, so are shown prominently.</p>
<p>There is an &#8220;advanced&#8221; checkbox. When clicked, this shows fields that should only be changed if you are sure of what they do:</p>
<p><a href="http://verens.com/wp-content/uploads/2009/08/bbpress2.jpg"><img src="http://verens.com/wp-content/uploads/2009/08/bbpress2.jpg" alt="bbpress2" title="bbpress2" width="300" height="154" class="aligncenter size-full wp-image-799" /></a></p>
<p>The fields shown here rarely need to be changed. They include database host, collation, character set and table prefix.</p>
<p>The default character set is UTF8, and I can&#8217;t imagine why anyone would need anything other than that (that also covers collation). My own opinion is that these ones shouldn&#8217;t even be in advanced &#8211; they should be hard-coded.</p>
<p>There are not many reasons why the table prefix would ever need to be changed, but in the case I was troubleshooting, the database host was held on a separate server to the site itself.</p>
<p>So, because the database host needed to be changed, that explains why the admin opened the Advanced section in the first place.</p>
<p>If the prefix input box was named &#8220;prefix&#8221;, this would be the end of the story &#8211; I might have assumed that the problem was autofill (as I did for a while), and suggest the above solution to them.</p>
<p>But, the authors of bbPress have obviously come across the autofill problem themselves, because they named their prefix button &#8220;bb_table_prefix&#8221;, exactly as I suggest every installer should do (now do it with WordPress, guys!):</p>
<pre>&lt;input <span style="color:#aaa;font-style:italic;">[...]</span> name="<strong>bb_table_</strong>prefix" class="text" value="bb_" tabindex="8" /&gt;</pre>
<p>So, the problem is not the software.</p>
<p>In this case, I believe it&#8217;s human error. What follows is my own guess at what happened, in hind-sight and without the benefit of watching the proceedings in person.</p>
<p>I think what happened is that our admin&#8217;s techie had left some notes about the settings used for the WordPress installation, including database username, password, etc. Then the admin had gone to install bbPress, in the correct assumption that installation should be straightforward and compatible with WordPress.</p>
<p>However, I believe the problem is that the techie had left a note about table prefix, but had not explained to the admin that all the other settings must be as written but the prefix <strong>must not</strong>.</p>
<p>The admin had simply filled in what was written, and bbPress did what it does, and changed WordPress&#8217;s database tables.</p>
<p>So, who&#8217;s at fault?</p>
<p>I believe the problem here was a misunderstanding &#8211; to all of us who have done a million installations of a thousand different software applications, it&#8217;s very obvious what the table prefix is, and what it does. However, I don&#8217;t believe I&#8217;ve ever seen it written down, or the dangers of using an existing value.</p>
<p>Let&#8217;s look at the bbPress installation again, this time with the &#8216;?&#8217; expanded:</p>
<p><a href="http://verens.com/wp-content/uploads/2009/08/bbpress3.jpg"><img src="http://verens.com/wp-content/uploads/2009/08/bbpress3.jpg" alt="bbpress3" title="bbpress3" width="400" height="70" class="aligncenter size-full wp-image-800" /></a></p>
<p>It says &#8220;If you are running multiple bbPress sites in a single database, you will probably want to change this.&#8221; While literally correct, this actually doesn&#8217;t explain what the prefix is or why it should be changed. And <strong>most importantly</strong>, it does not say &#8220;This value <strong>must</strong> be unique in your database, or it may overwrite your existing database tables.&#8221; The help text in bbPress&#8217;s case does not actually explain the danger of using existing values for the prefix.</p>
<p>The techie is also at fault. If leaving notes for someone, always make sure to explain anything which needs explaining. In this case, it should be something like &#8220;If installing new software, use these database access details, but make sure that you do not use these database table prefixes.&#8221; In fact, the table prefix should not have been in the notes at all &#8211; if the value is a default, then don&#8217;t write it down.</p>
<p>The admin is also at fault, for following the notes to the letter and filling in the prefix where the default value was actually perfect. I won&#8217;t fault him for installing software when the techie wasn&#8217;t at hand to point out mistakes, as there really shouldn&#8217;t have been any &#8211; the prefix error was actually quite easy to make; it just happened to have devastating effects.</p>
<p>However, these are all minor faults. They&#8217;re all easy mistakes to make, and it was the combination of all three that caused the error.</p>
<p>Having said all that, I realise that I have <a href="http://kfm.verens.com/">some</a> <a href="http://webme.eu/">installers</a> to check now to make sure I follow my own advice!</p>
]]></content:encoded>
			<wfw:commentRss>http://verens.com/archives/2009/08/04/a-tale-of-prefixes/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
