<?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>Torkil Johnsen</title>
	<atom:link href="http://www.torkiljohnsen.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.torkiljohnsen.com</link>
	<description>My personal piece of cyberspace</description>
	<lastBuildDate>Mon, 28 Nov 2011 11:18:55 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Nooku Jam Leuven 2011</title>
		<link>http://www.torkiljohnsen.com/2011/11/28/nooku-jam-leuven-2011/</link>
		<comments>http://www.torkiljohnsen.com/2011/11/28/nooku-jam-leuven-2011/#comments</comments>
		<pubDate>Mon, 28 Nov 2011 09:54:19 +0000</pubDate>
		<dc:creator>tj</dc:creator>
				<category><![CDATA[Nooku]]></category>

		<guid isPermaLink="false">http://www.torkiljohnsen.com/?p=757</guid>
		<description><![CDATA[Around 30 people, mostly developers, showed up for this weekend Nooku Jam in Leuven, Belgium, to learn about Nooku, where it&#8217;s headed, and to show off their work or collaborate with people on Nooku development. Personally, this was my first Nooku Jam, and I find myself regretting not having gone to one earlier. The Jam [...]]]></description>
			<content:encoded><![CDATA[<p>Around 30 people, mostly developers, showed up for this weekend Nooku Jam in Leuven, Belgium, to learn about Nooku, where it&#8217;s headed, and to show off their work or collaborate with people on Nooku development.<br />
<span id="more-757"></span><br />
Personally, this was my first Nooku Jam, and I find myself regretting not having gone to one earlier. The Jam was organized as a BarCamp, with the program being created as we went along: If you want a particular topic on the schedule, you just raise your hand and suggest it. Chances are good that someone else will be interested in the same thing, and you&#8217;ll get a timeslot and room dedicated to present or discuss the topic in question.</p>
<p><em>The informal setting</em> of the <a href="http://barcamp.org/" target="_blank">BarCamp</a>, combined with the nice venue of <a href="http://www.flandersdc.be/" target="_blank">Flanders DC</a> and general awesomeness of Nooku&#8217;ers, made this jam the perfect place to discuss code, ideas, to show and tell or do networking. With a good host/crew/moderator on site, the result is an event with interesting topics being discussed at all times. Running an event in the BarCamp format is definitely something I&#8217;d recommend.</p>
<h2>Where is Nooku headed</h2>
<p>Nooku will in 2012 introduce 4 month release cycles. First release will be in approximately January 2012, and will be numbered 12.1 (year.release number). That&#8217;s right: No more alphas, just releases. Second release of 2012 will be 12.2, and so forth. I filmed him talking about this too:</p>
<p><iframe width="480" height="274" src="http://www.youtube.com/embed/C_nI8uxi9Lg?rel=0" frameborder="0" allowfullscreen></iframe></p>
<p><a href="https://twitter.com/#!/torkilj/status/140723136357339136" target="_blank">There will be no backwards compatibility</a> between releases, but there will be documentation on how to migrate your code from one release to another. There will also be an updating system in place that will make it easy to upgrade your Nooku powered extension. For this to work though, developers of publicly available extensions need to follow the release cycles of the framework and upgrade their extensions regularly. After all, a website can&#8217;t have for instance both <a href="http://ninjaforge.com/extensions/ninjaboard" target="_blank">Ninjaboard</a> and <a href="http://app.ohanah.com/" target="_blank">Ohanah</a> installed if they&#8217;re running different framework versions.</p>
<blockquote><p>&#8220;If Google Chrome can do it, if Firefox can do it, if WordPress can do it, then so can we.&#8221;<br />
- Johan Janssens</p></blockquote>
<p>I think this is a great approach, because it forces us to stay up to date, and it removes old and outdated extensions from the mix on a regular basis. For the framework and Nooku Server, this also means that we can progress on the cutting edge parts, while not having to maintain 3-year old legacy code. Maintaining legacy code is expensive: For instance it requires resources that are better spent on moving the project forward, and it multiplies the amount of code you have to support.</p>
<blockquote><p>&#8220;If the requirement to upgrade your extensions regularly is not to your liking, then Nooku Framework is not for you.&#8221;<br />
- Johan Janssens</p></blockquote>
<h2>What features are on the roadmap</h2>
<p>Under the hood of Nooku Server and Nooku Framework, there is of course also a lot happening. Nooku Server is almost completely refactored now, and almost all the old Joomla 1.5 code has been replaced with Nooku Framework code. </p>
<p>I already mentioned the automatic upgrades, and there are plenty of other goodies floating around too, like logging, totally reusable files management, and other stuff that was demoed during the jam. Which features that will make it into the next releases though, remains to be seen.</p>
<p>A good way to stay on top of things is to pay attention to what is happening in the Nooku development branches.</p>
<h2>Collaboration and code sharing</h2>
<p>Plenty of sessions this weekend concerned code and code collaboration. With the number of developers increasing more and more, it&#8217;s become obvious that we on some parts are duplicating our efforts. Without a central place to share code between ourselves, or at least a place to get an overview of where collaboration is happening, it&#8217;s hard for developers to join forces on mutually beneficial projects.</p>
<p>Since any Nooku component, or part of a Nooku component, can be reused and called from outside the component itself, it enables us to reuse code and functionality to a much larger degree than what was the case back in the Joomla days. The architecture of it just makes it desirable to write code that is DRY, general and reusable, and that makes the opportunities for code collaboration so much greater; two projects may have completely different products, but they may still share a lot of stuff like versioning, file management, image processing, and so on. </p>
<p>In other news: Nooku will start using Git soon, and the Google Groups mailing list will be replaced with something else. Joomlatools have been working on a forum/ticketing/ideas tool, which they are going to release into the wild in the foreseeable future. In my opinion they are really leading by example as far as code sharing goes.</p>
<p><a href="https://twitter.com/#!/skore_de" target="_blank">David</a> has taken it upon himself to try to create a public map of the different developers and projects out there in the coming weeks to make it easier for people to find one another and start collaborating in the short term.</p>
<h2>Backend UI/UX</h2>
<p>A topic of special interest to myself was the backend UX/UI talk. Leading the discussion was <a href="https://twitter.com/#!/janssenstom" target="_blank">Tom Janssens</a>, designer of Nooku Server backend, <a href="https://twitter.com/#!/nickbalestra" target="_blank">Nick Balestra</a>, designer of Ohanah, and also the boss of templates and RocketTheme CEO, <a href="https://twitter.com/#!/rhuk" target="_blank">Andy Miller</a>.</p>
<p>With Nooku constantly reducing the amount of PHP code you need to write, the amount of HTML and CSS in a project is an increasing percentage. We discussed and agreed upon that there should be guidelines for how component backends should be coded, and that ideally you should be able to use predefined classes to make your backend look sexy, without having to write CSS at all basically. A uniform backend HTML/CSS across components also allows us to easily add responsiveness if we decide to, and it ensures that the end user of components gets a consistent experience whenever using Nooku extensions.</p>
<p>Sexiness will not only be associated with Nooku code, but also with Nooku looks and workflow.</p>
<p>Expect a Git repository to appear on this topic shortly. I am guessing <a href="https://twitter.com/#!/janssenstom" target="_blank">@janssenstom</a> will announce it both on twitter under <a href="https://twitter.com/#!/search/%23nooku" target="_blank">#Nooku</a>, and on the <a href="http://groups.google.com/group/nooku-framework" target="_blank">Nooku mailing list</a>.</p>
<h2>Wiki/documentation</h2>
<p>Another talk I participated in concerned the <a href="http://wiki.nooku.org" target="_blank">wiki</a> and documentation efforts. The documentation is having a hard time keeping up with development at the moment, and the wiki is not very newbie friendly; there is no clear <a href="https://nooku.assembla.com/spaces/nooku-framework/wiki/Developing_a_blog_component" target="_blank">starting point for beginners</a>. I have a phpDoc generator going that generates automatic <a href="http://torkiljohnsen.com/nooku-framework-documentation/" target="_blank">documentation of the Nooku Framework trunk</a> on a nightly basis, but that&#8217;s only useful to some, and not sufficient for all beginners. </p>
<p>What we want to do here is to organize and categorize the wiki content much better, and we want to cut back on wiki content to remove stuff that&#8217;s nice-to-have and place it somewhere else, so that the stuff that&#8217;s need-to-have gets a more prominent position.</p>
<p>Expect a mailing list call to action on this one from <a href="https://twitter.com/#!/FonnySmets" target="_blank">Fonny</a> and/or <a href="https://twitter.com/#!/peterraeves" target="_blank">Peter</a>.</p>
<h2>What I take home with me</h2>
<p>Speaking and listening to presentations by other developers who eagerly share their code and experiences, and getting to know and being able to work together with skilled people in an informal setting like this, is highly inspirational and educational. </p>
<p>Nooku has a relatively small and agile group of developers, which allows for quick development iterations, faster development and early adoption of new concepts. Nooku is driven forward by Johan Janssens and the people of Timble, but it has a flat organizational structure and low barriers for contribution, making it all the more interesting for people like myself. Having learned from the history of the Joomla project is definitely not a disadvantage.</p>
<p>I&#8217;d like to thank all the people that helped made this event happen, and I&#8217;m looking forward to following the progress of a lot of different things in the months to come. There is so much new stuff happening, that it would be hard to list it all in one blog post, but feel free to toss in your experiences in the comments below. I only attended less than 1/3 of the talks at the event, so there&#8217;s a lot more that can be said :)</p>
<p>The best thing to do for now is to keep an ear to the ground and listen for <a href="https://twitter.com/#!/search/%23nooku" target="_blank">#Nooku</a>, because there&#8217;s a stampede coming.</p>
<h2>Related links:</h2>
<p><a href="http://www.flickr.com/photos/valanx/sets/72157628152971783/with/6410166623/" target="_blank">Flickr photo set by David</a> (not updated with pictures from the last day at the time of this writing)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.torkiljohnsen.com/2011/11/28/nooku-jam-leuven-2011/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Issues after upgrading to OS X Lion</title>
		<link>http://www.torkiljohnsen.com/2011/07/21/issues-after-upgrading-to-os-x-lion/</link>
		<comments>http://www.torkiljohnsen.com/2011/07/21/issues-after-upgrading-to-os-x-lion/#comments</comments>
		<pubDate>Thu, 21 Jul 2011 11:14:21 +0000</pubDate>
		<dc:creator>tj</dc:creator>
				<category><![CDATA[mac]]></category>
		<category><![CDATA[mamp]]></category>
		<category><![CDATA[osx]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://www.torkiljohnsen.com/?p=748</guid>
		<description><![CDATA[I ran into a few issues after upgrading to OS X Lion that I thought might be useful to share with others. Table of contents VMware Fusion: Partition table has changed MAMP and OS X Lion NAS (Network Attached Storage) issues with AFP/remote Time Machine Lion install failed — Boot Camp issue More OS X Lion [...]]]></description>
			<content:encoded><![CDATA[<p>I ran into a few issues after upgrading to OS X Lion that I thought might be useful to share with others.<br />
<span id="more-748"></span></p>
<h2>Table of contents</h2>
<ol>
<li><a href="#vmware">VMware Fusion: Partition table has changed</a></li>
<li><a href="#mamp">MAMP and OS X Lion</a></li>
<li><a href="#nas">NAS (Network Attached Storage) issues with AFP/remote Time Machine</a></li>
<li><a href="#bootcamp">Lion install failed — Boot Camp issue</a></li>
<li><a href="#more">More OS X Lion tips</a></li>
</ol>
<hr />
<h2><a name="vmware"></a>1. VMware Fusion: Partition table has changed</h2>
<p>I could not start up my Windows 7 boot camp partition after the upgrade. The error message I got was something like this:</p>
<blockquote><p>
Cannot open the disk &#8216;/Users/torkil/Library/Application Support/VMware Fusion/Virtual Machines/Boot Camp/Boot Camp.vmwarevm/Boot Camp.vmdk&#8217; or one of the snapshot disks it depends on.</p>
<p>Reason: The partition table on the physical disk has changed since the disk was created. Remove the physical disk from the virtual machine, then add it again.
</p></blockquote>
<p>I found the solution to that issue on the <a href="http://blogs.vmware.com/teamfusion/2011/07/os-x-lion-spotted-in-the-wild.html?cid=6a00d8341c328153ef0153900c1f90970b#comment-6a00d8341c328153ef0153900c1f90970b">VMware Fusion blog comments</a>:</p>
<p>&#8220;That means to go into the Virtual Machine library and delete the entry. Then, create a new Bootcamp based VM. Your VM wouldnt be damaged as it is running bootcamp and just using that info. If that still doesnt work, boot using bootcamp itself.&#8221;</p>
<h2><a name="mamp"></a>2. MAMP and OS X Lion</h2>
<p>The popular MAMP (Mac Apache MySQL PHP) software needs to be version 2.0 for Lion compatibility. An upgrade is all it takes. See the <a href="http://www.mamp.info/en/downloads/index.html">MAMP download page</a>.</p>
<h2><a name="nas"></a>3. NAS (Network Attached Storage) issues with AFP/remote Time Machine</h2>
<p>I am trying to connect with AFP to a fileserver on our network at work. I am getting this error message after installing Lion:</p>
<blockquote><p>There was a problem with trying to connect to the server. The version of the server you&#8217;re trying to connect to is not supported.</p></blockquote>
<p>This is also a problem for people using TimeMachine to do backups to Synology&#8217;s file servers. The problem is that Synology&#8217;s firmware ships with an older version of Netatalk, not compatible with Lion. Synology already has a <a href="http://forum.synology.com/enu/viewtopic.php?f=180&#038;t=39029&#038;hilit=mac+os+10.7&#038;start=30#p154468">DSM 3.2 beta</a> which fixes the problems for many people it seems. Synology has also said that they are <a href="http://forum.synology.com/enu/viewtopic.php?f=64&#038;t=34294&#038;start=45#p153529">releasing version 3.2 at the end of July 2011</a>, and that this version will fix the problems.</p>
<p>Smallnetbuilder.com has <a href="http://www.smallnetbuilder.com/nas/nas-news/31540-lion-breaks-time-machine-nases">an article</a> on the topic, with a <a href="http://www.alexanderwilde.com/2011/04/os-x-lion-connection-error-with-afp-and-workaround/">link to a workaround</a> that Alexander Wilde has dug up. I have tested his solution now, and I can confirm that it works.</p>
<h2><a name="bootcamp"></a>4. Lion install failed — Boot Camp issue</h2>
<blockquote><p>Max OS X can’t be installed on the disk Macintosh HD, because a recovery system can’t be created. Visit www.apple.com/support/no-recovery to learn more.</p></blockquote>
<p>I ran into this problem on my wife&#8217;s Macbook Pro. The help article on apple.com suggests I format the entire computer and reinstall Snow Leopard and then install Lion again. Seems like too much work, so I&#8217;m going to try another recipe:</p>
<ol>
<li>Download and install <a href="http://download.cnet.com/Winclone/3000-2242_4-11089354.html">Winclone</a></li>
<li>Make a backup of my Boot Camp partition on my OS X harddrive with Winclone</li>
<li>Backup OS X to Time Machine</li>
<li>Use Boot Camp assistant to remove the Windows partition</li>
<li>Backup to Time Machine again (paranoid!)</li>
<li>Install Lion, hopefully without problems</li>
<li>Recreate the Boot Camp partition and use Winclone to recreate it like it used to be</li>
</ol>
<p>Thanks to Macworld tip on <a href="http://www.macworld.com/article/136529/2008/11/backupbootcamp.html">Backup and restore Boot Camp partitions</a>.</p>
<p>I&#8217;ll report back when I&#8217;ve tried this, and hopefully succeeded.</p>
<h2><a name="more"></a>5. More OS X Lion tips</h2>
<p>Here is some further reading:</p>
<ul>
<li><a href="http://techcrunch.com/2011/07/21/os-x-lion-new-features/">Techcrunch: Nine things you should do after installing OS X Lion</a></li>
</ul>
<h2>Have you experienced any problems?</h2>
<p>If you have found issues with other software after upgrading to OS X Lion, feel free to post it in the comments below.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.torkiljohnsen.com/2011/07/21/issues-after-upgrading-to-os-x-lion/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Nooku Framework API documentation</title>
		<link>http://www.torkiljohnsen.com/2011/03/29/nooku-framework-api-documentation/</link>
		<comments>http://www.torkiljohnsen.com/2011/03/29/nooku-framework-api-documentation/#comments</comments>
		<pubDate>Tue, 29 Mar 2011 16:54:39 +0000</pubDate>
		<dc:creator>tj</dc:creator>
				<category><![CDATA[Nooku]]></category>

		<guid isPermaLink="false">http://www.torkiljohnsen.com/?p=745</guid>
		<description><![CDATA[I recently set up an automatically updated site that uses PhpDocumentor to create the API documentation for the Nooku Framework. The site is updated every night with the latest version of the Nooku Framework, and you can also read the complete source code of every php-file and class in the framework. Keep an eye out [...]]]></description>
			<content:encoded><![CDATA[<p>I recently set up an automatically updated site that uses PhpDocumentor to create the API documentation for the Nooku Framework. The site is updated every night with the latest version of the Nooku Framework, and you can also read the complete source code of every php-file and class in the framework. Keep an eye out on <a href="http://api.nooku.org">api.nooku.org</a> too, as we will be working on improving it too in the near future.</p>
<p>Go to the <a class="more-link" href="http://torkiljohnsen.com/nooku-framework-documentation/">Nooku Framework API documentation</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.torkiljohnsen.com/2011/03/29/nooku-framework-api-documentation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Split views using Nooku Framework</title>
		<link>http://www.torkiljohnsen.com/2010/12/28/split-views-using-nooku-framework/</link>
		<comments>http://www.torkiljohnsen.com/2010/12/28/split-views-using-nooku-framework/#comments</comments>
		<pubDate>Tue, 28 Dec 2010 08:09:09 +0000</pubDate>
		<dc:creator>tj</dc:creator>
				<category><![CDATA[Nooku]]></category>
		<category><![CDATA[HMVC]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://www.torkiljohnsen.com/?p=739</guid>
		<description><![CDATA[Stian Didriksen wrote a good tutorial on using split views in Nooku Framework. A split view is a UI pattern where a view consists of two side-by-side panes, typically a left side menu with a right side detail views. In this tutorial he shows how to load these parts with HMVC and Ajax. Read more [...]]]></description>
			<content:encoded><![CDATA[<p>Stian Didriksen wrote a good tutorial on using split views in Nooku Framework. A split view is a UI pattern where a view consists of two side-by-side panes, typically a left side menu with a right side detail views. In this tutorial he shows how to load these parts with HMVC and Ajax. </p>
<p><a href="http://blog.nooku.org/2010/12/split-views-using-nooku-framework/" class="more-link">Read more at the Nooku blog</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.torkiljohnsen.com/2010/12/28/split-views-using-nooku-framework/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using Gmail? Tried &#8220;dynamic&#8221; aliases?</title>
		<link>http://www.torkiljohnsen.com/2010/12/13/using-gmail-dynamic-aliases/</link>
		<comments>http://www.torkiljohnsen.com/2010/12/13/using-gmail-dynamic-aliases/#comments</comments>
		<pubDate>Mon, 13 Dec 2010 16:33:35 +0000</pubDate>
		<dc:creator>tj</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[alias]]></category>
		<category><![CDATA[filter]]></category>
		<category><![CDATA[gmail]]></category>
		<category><![CDATA[spam]]></category>

		<guid isPermaLink="false">http://www.torkiljohnsen.com/?p=735</guid>
		<description><![CDATA[While GMail does not offer traditional aliases to be set up for your_name@gmail.com, but you can get dynamic aliases that you can add on the fly when providing your e-mail address to someone. This comes in handy when registering on websites or subscribing to newsletters. GMail is normally really good at filtering spam, but sometimes [...]]]></description>
			<content:encoded><![CDATA[<p>While GMail does not offer traditional aliases to be set up for your_name@gmail.com, but you can get dynamic aliases that you can add on the fly when providing your e-mail address to someone. This comes in handy when registering on websites or subscribing to newsletters.<br />
<span id="more-735"></span><br />
GMail is normally really good at filtering spam, but sometimes you&#8217;ll still get e-mails with offers for buying this or investing in that. Many of the senders also kindly allow you to unsubscribe to their newsletter, but maybe you didn&#8217;t want it in the first place? Where have they picked up your mail address? Scraped it off the internet? Bought it?</p>
<p>I recently also saw <a href="http://twitter.com/#!/FxNxRL/status/14317854442659840">a tweet</a> concerning DeviantART&#8217;s mailing list having been compromised, and a lot of people&#8217;s e-mail addresses have probably now ended up in the hands of spammers. The person tweeting luckily had an alias set up that he could just kill off to avoid being spammed any further.</p>
<p><strong>GMail has this nice little feature</strong> that allows you use your_name+whatever@gmail.com as your e-mail address. So for each new site you register on you can use a new address. For DeviantART you could use your_name+deviantart@gmail.com for instance. This makes it easier to find out who has lost or sold your e-mail address in the future, and it makes it really easy to block unwanted mail with a quick filter.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.torkiljohnsen.com/2010/12/13/using-gmail-dynamic-aliases/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Table Behaviors in Nooku Framework</title>
		<link>http://www.torkiljohnsen.com/2010/12/07/table-behaviors-in-nooku-framework/</link>
		<comments>http://www.torkiljohnsen.com/2010/12/07/table-behaviors-in-nooku-framework/#comments</comments>
		<pubDate>Tue, 07 Dec 2010 19:00:35 +0000</pubDate>
		<dc:creator>tj</dc:creator>
				<category><![CDATA[Nooku]]></category>

		<guid isPermaLink="false">http://www.torkiljohnsen.com/?p=561</guid>
		<description><![CDATA[One of the great timesavers in Nooku Framework are the database table behaviors. As the name suggests, you can use these to add some behaviors to your database. Here is a tutorial on how these work, plus a few practical examples. Table of contents Dual purpose How to add a behavior By identifier By instance [...]]]></description>
			<content:encoded><![CDATA[<p>One of the great timesavers in Nooku Framework are the database table behaviors. As the name suggests, you can use these to add some behaviors to your database. Here is a tutorial on how these work, plus a few practical examples.<br />
<span id="more-561"></span></p>
<h2>Table of contents</h2>
<ol class="toc">
<li><a href="#purpose">Dual purpose</a></li>
<li><a href="#how_to_add">How to add a behavior</a>
<ol>
<li><a href="#add_by_id">By identifier</a></li>
<li><a href="#add_by_instance">By instance</a></li>
</ol>
</li>
<li><a href="#where_to_add">Where to add a behavior</a>
<ol>
<li><a href="#add_to_table">In the table class</a></li>
<li><a href="#add_to_model">In the model class</a></li>
</ol>
</li>
<li><a href="#defaults">Nooku&#8217;s built in behaviors</a></li>
<li><a href="#creating">Creating your own behaviors</a></li>
<li><a href="#joomla_comparison">Comparing to Joomla 1.6</a></li>
<li><a href="#automated_events">Revelation: Automated plugin events/hooks</a></li>
<li><a href="#row_mixins">Revelation 2: Row mixins</a></li>
<li><a href="#references">References and further reading</a></li>
</ol>
<hr style="display:block; margin-top: 2em;"/>
<p><a name="purpose"></a><br />
<h2>Dual purpose</h2>
<p>The behaviors are something of a cross-breed between database triggers and database row mixins. Confused?</p>
<p>Database behaviors can first of all <strong>intercept table commands</strong>, meaning they can act on any select, update, delete and insert being run on your database, much like a database trigger, but with PHP-code, and thus a lot more flexible. For example: When selecting an article from a database table that has a column called &#8220;hits&#8221; and a behavior called &#8220;hittable&#8221;, the value of the hit column will increment automatically. </p>
<p>At the same time, the behaviors function as <strong>row and rowset <em>mixins</em></strong>. <a href="http://en.wikipedia.org/wiki/Mixin">Mixins</a> are a way of doing multiple inheritance, something PHP does not support natively. So while your own table class may extend KDatabaseTable, it can also mix in KDatabaseBehaviorLockable, so you&#8217;ll get access to the public functions from the latter too.</p>
<p>The main idea is to make a flexible and reusable implementation based on composition, rather than one which relies on inheritance; Behaviors can be added to your code and triggered dynamically, so instead of having for example a &#8220;hit&#8221; method in a base model that all models inherit from, or worse, copying a &#8220;hit&#8221; method across your models, you can just mix in the behavior where it&#8217;s needed. </p>
<p><a name="how_to_add"></a><br />
<h2>How to add a behavior</h2>
<p>Behaviors are added to database table classes, either when initializing the database table class, or when constructing the related model class. When adding behaviors, you can either add by identifier or add by instance.</p>
<p><a name="add_by_id"><br />
<h3>Adding by identifier</h3>
<p>If you&#8217;re using a Nooku core behavior, you can use the behavior&#8217;s shortname directly, like &#8220;lockable&#8221; or &#8220;creatable&#8221;. </p>
<p>If you wish to use a behavior you created yourself, or reuse a behavior from another component, you can easily do so by specifying the full identifier. For instance: &#8220;admin::com.shop.database.behavior.notifiable&#8221; to reuse the notifiable behavior from com_shop.</p>
<p>When adding by identifier, the behavior object itself is created for you, with it&#8217;s default configuration.</p>
<p></a><a name="add_by_instance"><br />
<h3>Adding by instance</h3>
<p>You can also add a ready-made object in itself if you wish, by calling a factory method to create the object first:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1"><span class="co1">// using the behavior's shortname</span>
<span class="re0">$sluggable</span> <span class="sy0">=</span> KDatabaseBehavior<span class="sy0">::</span><span class="me2">factory</span><span class="br0">&#40;</span><span class="st_h">'sluggable'</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
<span class="co1">// using an identifier string</span>
<span class="re0">$notifiable</span> <span class="sy0">=</span> KDatabaseBehavior<span class="sy0">::</span><span class="me2">factory</span><span class="br0">&#40;</span><span class="st_h">'admin::com.shop.database.behavior.notifiable'</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div></div></div></div></div></div>


<p>Some behaviors also accept a configuration array, which can be specified like this:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1"><span class="co1">// use id and title for item slugs, instead of just title</span>
<span class="re0">$sluggable</span> <span class="sy0">=</span> KDatabaseBehavior<span class="sy0">::</span><span class="me2">factory</span><span class="br0">&#40;</span>
    <span class="st_h">'sluggable'</span><span class="sy0">,</span> <span class="kw3">array</span><span class="br0">&#40;</span><span class="st_h">'columns'</span> <span class="sy0">=&gt;</span> <span class="kw3">array</span><span class="br0">&#40;</span><span class="st_h">'id'</span><span class="sy0">,</span> <span class="st_h">'title'</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
<span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div></div></div></div></div></div>


<p>In this case, &#8220;sluggable&#8221; can also of course be replaced by a full identifier.</p>
<p></a><a name="where_to_add"></a><br />
<h2>Where to add a behavior</h2>
<p>To use a behavior with your table class, you can either add it during database table initialization, or you can add it during model construction.</p>
<p><a name="add_to_table"><br />
<h3>Adding during table initialization</h3>
<p>You can add behaviors by shortname, identifier string or instance, and you can add multiple at a time. Here, I&#8217;m adding two behaviors to my books table:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1"><span class="kw2">class</span> ComLibraryDatabaseTableBooks <span class="kw2">extends</span> KDatabaseTableAbstract 
<span class="br0">&#123;</span>
    <span class="kw2">protected</span> <span class="kw2">function</span> _initialize<span class="br0">&#40;</span>KConfig <span class="re0">$config</span><span class="br0">&#41;</span>
    <span class="br0">&#123;</span>
        <span class="co1">// make the library's books lockable and hittable</span>
        <span class="re0">$config</span><span class="sy0">-&gt;</span><span class="me1">behaviors</span> <span class="sy0">=</span> <span class="kw3">array</span><span class="br0">&#40;</span><span class="st_h">'lockable'</span><span class="sy0">,</span> <span class="st_h">'hittable'</span><span class="br0">&#41;</span><span class="sy0">;</span>
        parent<span class="sy0">::</span>_initialize<span class="br0">&#40;</span><span class="re0">$config</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="br0">&#125;</span>
<span class="br0">&#125;</span></pre></div></div></div></div></div></div></div>


<p></a><a name="add_to_model"><br />
<h3>Adding during model construction</h3>
<p>Here I&#8217;m adding the behavior in the models constructor, and also doing it by adding a pre-configured object instance.</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1"><span class="kw2">class</span> ComLibraryModelBooks <span class="kw2">extends</span> KModelDefault
<span class="br0">&#123;</span>
    <span class="kw2">public</span> <span class="kw2">function</span> __construct<span class="br0">&#40;</span>KConfig <span class="re0">$config</span><span class="br0">&#41;</span> 
    <span class="br0">&#123;</span>
        <span class="co1">// use id and title for item slugs</span>
        <span class="re0">$sluggable</span> <span class="sy0">=</span> KDatabaseBehavior<span class="sy0">::</span><span class="me2">factory</span><span class="br0">&#40;</span>
            <span class="st_h">'sluggable'</span><span class="sy0">,</span> <span class="kw3">array</span><span class="br0">&#40;</span><span class="st_h">'columns'</span> <span class="sy0">=&gt;</span> <span class="kw3">array</span><span class="br0">&#40;</span><span class="st_h">'id'</span><span class="sy0">,</span> <span class="st_h">'title'</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
        <span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
        <span class="re0">$config</span><span class="sy0">-&gt;</span><span class="me1">append</span><span class="br0">&#40;</span><span class="kw3">array</span><span class="br0">&#40;</span>
            <span class="st_h">'table_behaviors'</span> <span class="sy0">=&gt;</span> <span class="kw3">array</span><span class="br0">&#40;</span><span class="re0">$sluggable</span><span class="br0">&#41;</span>
        <span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
        parent<span class="sy0">::</span>__construct<span class="br0">&#40;</span><span class="re0">$config</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="br0">&#125;</span>
<span class="br0">&#125;</span></pre></div></div></div></div></div></div></div>


<p>Notice how I am not calling KFactory to create the behavior objects. Instead I am calling <em>KDatabaseBehavior::factory</em> which wraps around KFactory::tmp. This enables me to instantiate the core behavior classes with just their shortnames, instead of their full identifier string. It will also verify that the object created is in fact extending KDatabaseBehaviorInterface. </p>
<p>You could also have written this to get a sluggable behavior object created for you:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1"><span class="re0">$sluggable</span> <span class="sy0">=</span> KFactory<span class="sy0">::</span><span class="me2">tmp</span><span class="br0">&#40;</span><span class="st_h">'lib.koowa.database.behavior.sluggable'</span><span class="br0">&#41;</span><span class="sy0">;</span></pre></div></div></div></div></div></div></div>


<p><strong>So where should you add the behavior?</strong> If you have either a model <em>or</em> a table class, then add it to the class that already exists. If you have both, add it to your table class. If you have none, you&#8217;ll need a table class to add the behavior too.  </p>
<p></a><a name="defaults"></a><br />
<h2>Nooku&#8217;s built-in behaviors</h2>
<p>Nooku&#8217;s core database table behaviors can be found in <a href="https://www.assembla.com/code/nooku-framework/subversion/nodes/trunk/code/libraries/koowa/database/behavior">libraries/koowa/database/behavior</a> of the <a href="https://nooku.assembla.com/code/nooku-framework/subversion/nodes">Nooku Framework repository</a>. At the time of this writing, the core behaviors are:</p>
<dl>
<dt>creatable</dt>
<dd>Use this to record who creates items and when. Triggered before an insert, and will auto-fill any created_by and created_on columns in your table. You won&#8217;t even need to have these fields in your form for this to be stored in the database.</dd>
<dt>hittable</dt>
<dd>Requires a hits column that will count the number of hits your items get. Just call the hit method whenever you want to increment the hit counter.</dd>
<dt>identifiable</dt>
<dd>Requires a column named uuid. This behavior will auto-create a <a href="http://en.wikipedia.org/wiki/UUID">Universally Unique IDentifier</a> when a row is created.</dd>
<dt>lockable</dt>
<dd>For people who know Joomla, you will know this behavior by the name check in/check out. This behavior will make a row editable or uneditable, to prevent simultaneous editing by two people. This behavior requires two columns in your table: locked_by and locked_on.</dd>
<dt>modifiable</dt>
<dd>This behavior helps you manage the columns modified_on and modified_by, which will keep track of who edited an item last, and when they edited it.</dd>
<dt>orderable</dt>
<dd>Requires an ordering column in your table. Mixes in an order method which you can use to reorder elements. It also keeps your your items in order when updating items in, or deleting items from, your database table.</dd>
<dt>sluggable</dt>
<dd>Will automatically create a <a href="http://en.wikipedia.org/wiki/Slug_(web_publishing)">slug</a> for a newly created item. It will create the slug from the column or columns you specify, default is the title column. It also uses the separator that you specify, and defaults to a dash. You can also configure this to be updatable or not, and set a length limit for the slugs created.</dd>
</dl>
<p><a name="creating"></a><br />
<h2>Creating your own behaviors</h2>
<p>Behaviors should be placed in (/administrator)/components/com_yourcomponent/databases/behaviors/, for instance with the file name behaviorname.php. The class should then be named ComYourcomponentBehaviorBehaviorname and it should extend KDatabaseBehaviorAbstract.</p>
<p>Here is a very simple example example in the shape of a <strong>&#8220;notifiable&#8221; behavior</strong>, which sends a notification when a new row is inserted in a database table. I am writing this for an imaginary component called &#8220;com_shop&#8221;, where I need notifications when new orders come in.</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1"><span class="sy0">&lt;</span> ?php
<span class="kw2">class</span> ComShopDatabaseBehaviorNotifiable <span class="kw2">extends</span> KDatabaseBehaviorAbstract
<span class="br0">&#123;</span>
    <span class="kw2">protected</span> <span class="kw2">function</span> _afterTableInsert<span class="br0">&#40;</span>KCommandContext <span class="re0">$context</span><span class="br0">&#41;</span>
    <span class="br0">&#123;</span>
        <span class="re0">$row</span> <span class="sy0">=</span> <span class="re0">$context</span><span class="sy0">-&gt;</span><span class="me1">data</span><span class="sy0">;</span> <span class="co1">// the new row object</span>
        <span class="kw1">return</span> <span class="kw3">mail</span><span class="br0">&#40;</span>
            <span class="st_h">'myname@mydomain.com'</span><span class="sy0">,</span> 
            <span class="st_h">'New order placed by '</span><span class="sy0">.</span><span class="re0">$row</span><span class="sy0">-&gt;</span><span class="me1">customer_name</span><span class="sy0">,</span> 
            <span class="st_h">'Here are the order details (more data here)'</span>
        <span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="br0">&#125;</span>
<span class="br0">&#125;</span></pre></div></div></div></div></div></div></div>


<p>I have here used _afterTableInsert, but remember that you can use any trigger after and before both insert, select, update and delete. For instance _afterTableDelete, if you need to do some cleanup after a delete for instance.</p>
<p>I then need to use the notifiable behavior in my orders table, where the new orders are registered:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="php"><pre class="de1"><span class="sy0">&lt;</span> ?php
<span class="kw2">class</span> ComShopDatabaseTableOrders <span class="kw2">extends</span> KDatabaseTableAbstract
<span class="br0">&#123;</span>
    <span class="kw2">protected</span> <span class="kw2">function</span> _initialize<span class="br0">&#40;</span>KConfig <span class="re0">$config</span><span class="br0">&#41;</span>
    <span class="br0">&#123;</span>
        <span class="re0">$config</span><span class="sy0">-&gt;</span><span class="me1">behaviors</span> <span class="sy0">=</span> <span class="kw3">array</span><span class="br0">&#40;</span><span class="st_h">'notifiable'</span><span class="br0">&#41;</span><span class="sy0">;</span>
        parent<span class="sy0">::</span>_initialize<span class="br0">&#40;</span><span class="re0">$config</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="br0">&#125;</span>
<span class="br0">&#125;</span></pre></div></div></div></div></div></div></div>


<p>This is of course very simple and you&#8217;d of course never use the mail() function for something like this, but it&#8217;s just an example.</p>
<p><strong>So why did I pick &#8220;notifiable&#8221; as an example?</strong> Well, notifications is something that could be useful in many cases. For instance: New client signups, new orders, new comment submissions, altered order statuses (use _afterTableUpdate for that) and so on. The trick is to make the code generic enough so it can be reused in multiple components. </p>
<p>If a behavior is deemed to be general and useful enough, it might be accepted into the core too, so perhaps you&#8217;re feeling up for the task and want to become the <a href="http://blog.nooku.org/2010/12/how-i-became-a-nooku-contributor/">next Nooku Contributor rockstar</a>?</p>
<p><a name="joomla_comparison"></a><br />
<h2>Comparing to Joomla 1.6</h2>
<p>Let&#8217;s look at how the Nooku core database behaviors are solved in Joomla 1.6. I am comparing this to 1.6 beta 15, as that is the most recent release at the time of this writing.</p>
<dl>
<dt>creatable</dt>
<dd>You will have to submit created and created_by variables with your form.</dd>
<dt>hittable</dt>
<dd>You&#8217;ll need to write this code yourself. For com_content there is a hardcoded function called hit in ContentModelArticle, but it will only work for com_content.</dd>
<dt>identifiable</dt>
<dd>Non-existant in Joomla 1.6 as far as I know.</dd>
<dt>lockable</dt>
<dd>A quick search in the codebase reveals at least eight different definitions of a function called &#8220;checkin&#8221;, where many seem to do the exact same thing; checkin/unlock a row item. So it appears as if there is a lot of code duplication here.</dd>
<dt>modifiable</dt>
<dd>You will have to submit modified and modified_by variables with your form.</dd>
<dt>orderable</dt>
<dd>If you extend JTableNested, you&#8217;ll have access to the functions orderUp, orderDown, move, moveByReference and saveorder, as far as I can tell.</dd>
<dt>sluggable</dt>
<dd>Slug is called alias in Joomla. The generation of an alias usually happens in a table class, but it&#8217;s all hardcoded in all core components, which means a lot of code duplication and copy pasting when writing components.</dd>
</dl>
<p><a name="automated_events"></a><br />
<h2>Revelation: Automated plugin events/hooks</h2>
<p>This also reveals a small piece of another puzzle, the <strong>table command chain</strong>. We have now seen how we can perform actions on certain events like the afterTableInsert example above. In Joomla (both 1.5 and 1.6) you have to manually trigger events like &#8220;onContentBeforeSave&#8221;; in Nooku, these exist by default, in all components.</p>
<p>One might argue that there are more plugin triggers in Joomla, like in the example class plgContentExample you can find onContentChangeState for instance. In Nooku, all actions also translates to one of the core BREAD actions; Browse, Read, Edit, Add, Delete. The difference between Browse and Read is that Browse equals &#8220;read multiple&#8221;, while Read equals &#8220;read one&#8221;. Changing the state of an item usually means changing the state column of a database row, which equals an edit operation. So if you want to create something equivalent to onContentChangeState, you&#8217;d just use for instance afterTableUpdate and do $row->getModified() to see if &#8220;state&#8221; has changed. </p>
<p>You can find the same <strong>command chain design pattern</strong> in the controllers, where events both before and after the different BREAD actions are triggered, like controllerBeforeRead. Nicholas Dionysopoulos used this concept in a <a href="http://www.assembla.com/wiki/show/nooku-framework/Server-side_input_validation">great tutorial</a> where he demonstrated server side validation by command chain usage in Nooku Framework.</p>
<p><a name="row_mixins"></a><br />
<h2>Revelation 2: Row mixins</h2>
<p>Let&#8217;s not forget the mixin part of the equation here, <a href="https://nooku.assembla.com/code/nooku-framework/subversion/nodes/trunk/code/libraries/koowa/database/behavior/lockable.php">the lockable behavior</a> is a good example of that: It exposes the lock, unlock, locked and lockMessage functions to the row object.</p>
<p>These are in turn used in the core controllers, like <a href="https://nooku.assembla.com/code/nooku-framework/subversion/nodes/trunk/code/libraries/koowa/controller/view.php">KControllerView</a>, to control access to the row object. Easy reuse of code in other words.</p>
<p><a name="references"></a><br />
<h2>References and further reading</h2>
<ul>
<li>Johan Janssens wrote the original <a href="http://groups.google.com/group/nooku-framework/msg/f91b57378e999dcc">introduction to database table behaviors</a> on Dec. 27th 2009.</li>
<li>On Nov. 7th 2010, Johan wrote <a href="http://groups.google.com/group/nooku-framework/browse_thread/thread/212f460783311d3b/1ace04bca2729922#1ace04bca2729922">another and more detailed explanation of how behaviors work</a>.</li>
<li>Another favorite: <a href="http://www.slideshare.net/HermanPeeren/design-patterns-illustrated ">Herman Peeren&#8217;s design patterns illustrated presentation</a>, which includes info on both the command chain and mixin patterns.</li>
<li>The <strong>revisable behavior</strong> is a more complex behavior belonging to the revisions component. For now, this is located in the <a href="https://nooku.assembla.com/code/nooku-components/subversion/nodes/trunk/code/administrator/components/com_versions/databases/behaviors/revisable.php">Nooku Components repository</a>. This behavior is part of a component still in development, but it already can provide full version control for your content, and the code is totally reusable.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.torkiljohnsen.com/2010/12/07/table-behaviors-in-nooku-framework/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Facebook API tutorial with PHP SDK</title>
		<link>http://www.torkiljohnsen.com/2010/12/06/facebook-api-tutorial-with-php-sdk/</link>
		<comments>http://www.torkiljohnsen.com/2010/12/06/facebook-api-tutorial-with-php-sdk/#comments</comments>
		<pubDate>Mon, 06 Dec 2010 21:37:47 +0000</pubDate>
		<dc:creator>tj</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[facebook api]]></category>
		<category><![CDATA[facebook sdk]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://www.torkiljohnsen.com/?p=590</guid>
		<description><![CDATA[Joey Rivera wrote a nice tutorial where he demonstrates how to use the Facebook PHP SDK to interact with Facebook&#8217;s Graph API. He presents a few simple examples where he starts out by creating a Facebook Application, and then goes on to both read and add photos and a status message. It&#8217;s a short and [...]]]></description>
			<content:encoded><![CDATA[<p>Joey Rivera wrote a nice tutorial where he demonstrates how to use the Facebook PHP SDK to interact with Facebook&#8217;s Graph API. He presents a few simple examples where he starts out by creating a Facebook Application, and then goes on to both read and add photos and a status message. It&#8217;s a short and sweet tutorial, and really easy to get into.<br />
<a class="more-link" href="http://www.joeyrivera.com/2010/facebook-graph-api-app-easy-w-php-sdk/">Read more at joeyrivera.com</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.torkiljohnsen.com/2010/12/06/facebook-api-tutorial-with-php-sdk/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Joomla 1.6 caching explained</title>
		<link>http://www.torkiljohnsen.com/2010/10/05/joomla-1-6-caching-explained/</link>
		<comments>http://www.torkiljohnsen.com/2010/10/05/joomla-1-6-caching-explained/#comments</comments>
		<pubDate>Tue, 05 Oct 2010 09:00:39 +0000</pubDate>
		<dc:creator>tj</dc:creator>
				<category><![CDATA[joomla]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[caching]]></category>
		<category><![CDATA[joomla 1.6]]></category>

		<guid isPermaLink="false">http://www.torkiljohnsen.com/?p=554</guid>
		<description><![CDATA[Klas Berli&#x10D, the man mainly responsible for the rewritten cache functionality in Joomla 1.6, has written two nice articles that explains the different types of caching available in Joomla 1.6. Joomla 1.6 caching explained Joomla 1.6 caching for developers]]></description>
			<content:encoded><![CDATA[<p>Klas Berli&#x10D, the man mainly responsible for the rewritten cache functionality in Joomla 1.6, has written two nice articles that explains the different types of caching available in Joomla 1.6.</p>
<p><a href="http://www.bzzzz.biz/blog/joomla/joomla-1.6-caching-demistified-jennifer-series.bzzzz" class="more-link">Joomla 1.6 caching explained</a></p>
<p><a href="http://www.bzzzz.biz/blog/joomla/joomla-1.6.-cache-changes-for-extension-developers-jennifer-series-2.bzzzz" class="more-link">Joomla 1.6 caching for developers</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.torkiljohnsen.com/2010/10/05/joomla-1-6-caching-explained/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Collection of Joomla Security Tips</title>
		<link>http://www.torkiljohnsen.com/2010/09/18/collection-of-joomla-security-tips/</link>
		<comments>http://www.torkiljohnsen.com/2010/09/18/collection-of-joomla-security-tips/#comments</comments>
		<pubDate>Sat, 18 Sep 2010 12:11:40 +0000</pubDate>
		<dc:creator>tj</dc:creator>
				<category><![CDATA[joomla]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://www.torkiljohnsen.com/?p=405</guid>
		<description><![CDATA[This is a post where I have collected a lot of tips and links from wherever I could find them. Originally I was going to wait for Joomla 1.6 to publish this and make sure to adjust the list according to what 1.6 will look like, but 1.6 is still in beta, and I grow [...]]]></description>
			<content:encoded><![CDATA[<p>This is a post where I have collected a lot of tips and links from wherever I could find them. Originally I was going to wait for Joomla 1.6 to publish this and make sure to adjust the list according to what 1.6 will look like, but 1.6 is still in beta, and I grow tired of waiting, so this is a list targeted at Joomla 1.5.<br />
<span id="more-405"></span><br />
<b>Disclaimer:</b> This post is <em>not</em> to be considered final by any means. Please help out people like yourself by adding more stuff to the comments or tweet them to me <a href="http://twitter.com/torkilj">@torkilj</a>, and I&#8217;ll update this list accordingly! </p>
<h2>Table of contents</h2>
<ol>
<li><a href="#choosing_a_host">Choosing a host for your Joomla site</a></li>
<li><a href="#installation">Installation</a></li>
<li><a href="#setup_and_configuration">Setting up and configuring the website</a></li>
<li><a href="#running_the_website">Running the website</a></li>
<li><a href="#developer_checklist">Developer&#8217;s checklist</a></li>
<li><a href="#if_you_get_hacked">What to do if your site gets hacked</a></li>
<li><a href="#resources">Further reading, other resources</a></li>
<li><a href="#acknowledgements">Acknowledgements</a></li>
</ol>
<hr style="display:block; margin-top: 2em;" />
<a name="choosing_a_host"></a><br />
<h2>Choosing a host for your Joomla site</h2>
<p>First of all, you should find a proper hosting provider. You could ask others in the Joomla community for their recommendations, and you could check out the <a href="http://resources.joomla.org/directory/support-services/hosting.html">shortlist of hosting providers</a> on the Joomla Resource Directory. These have at least gone through a manual screening process where their server setup has been checked for the most common pitfalls. </p>
<p>If you&#8217;re considering a host, here&#8217;s a brief list of requirements that you can run by your hosting provider to see if they fit the bill:</p>
<ol start="1">
<li>
<h3>Secure communication</h3>
<p>Make sure your host supports secure connections. It will cost you around $30/year to get a 256-bit SSL certificate to secure your backend. If you need to transfer files, make sure that SFTP or SCP is an available option to you, instead of having to use plain FTP.
</li>
<li>
<h3>PHP configuration</h3>
</li>
<ul>
<li>As with any software: Don&#8217;t use outdated versions, like PHP4</li>
<li>Disable potentially harmful PHP functions</li>
<li>Use open_basedir (with care, see comments after this article by Nicholas)</li>
<li>Turn magic quotes off</li>
<li>Don&#8217;t register globals</li>
<li>Allow users to set local php.ini files</li>
</ul>
<li>
<h3>Apache configuration</h3>
</li>
<ul>
<li>Enable .htaccess</li>
<li>Enable mod_rewrite</li>
<li>Enable mod_security</li>
<li>Enable suPHP</li>
</ul>
</ol>
<p><a name="installation"></a><br />
<h2>Installation</h2>
<ol start="4">
<li>
<h3>Connect securely</h3>
<p>Use SFTP or SSH when you connect to your server, and do not store your password in for instance your FTP client. This of course also goes for any subsequent connections to the server after you have finished your install.
</li>
<li>
<h3>Follow your own best practices</h3>
<p>If you have already set up one site where you follow all the basic security measures you want to follow, and you have already implemented the security extensions of your choice, there is no need to reinvent the wheel: Use a backup tool like <a href="http://extensions.joomla.org/extensions/access-a-security/site-security/backup/1606">Akeeba Backup</a> or something similar, take a backup of the site and use that backup as a starting point for your new site.</p>
<p>Kudos to <a href="http://twitter.com/hermanpeeren">@hermanpeeren</a> for the tip!
</li>
<li>
<h3>Do not use the standard DB prefix jos_. </h3>
<p> Many SQL injection attacks are based on the assumption that your database tables are named &#8220;jos_&#8221;. In case you did use jos_, you can still <a href="http://magazine.joomla.org/topics/item/108-the-prefix-has-nothing-to-do-with-telephony">change it with a simple PHP script</a>.</li>
<li>
<h3>One database user per installation</h3>
<p> Do not give the same database user access to multiple installations, and do not use the server&#8217;s root user for your database connection.</li>
<li>
<h3>Consider db user password quality</h3>
<p> Use a long and complicated password for your database, and when installation is done, for your login. It&#8217;s too easy to decrypt an MD5 or SHA1 hash these day. There are even <a href="http://md5.web-max.ca/">webapps that help you do it</a>. If someone gets hold of your database of hashed passwords, it&#8217;s only a matter of time before they are broken. There are lots of good tips for password quality in this previous article I wrote, &#8220;<a href="http://www.torkiljohnsen.com/2010/08/18/how-to-create%E2%80%94and-remember%E2%80%94a-different-password-for-every-single-login/">How to create—and remember—a different password for every single login</a>&#8220;, and there are also a lot of good tips in the article&#8217;s comments.</p>
<p>In general, when it comes to passwords: Don&#8217;t write them down anywhere, and if you have to, at least <a href="http://www.torkiljohnsen.com/2010/09/18/collection-of-joomla-security-tips/#comment-81103415">store them securely</a>.</li>
<li>
<h3>Don&#8217;t install sample content</h3>
<p> Sample content identifies you and your installation, and makes you easy to find and target. Don&#8217;t install sample content on what is to be a live website, because forgetting to remove absolutely all sample content is just too easy. </li>
</ol>
<p><a name="setup_and_configuration"></a><br />
<h2>Setting up and configuring the website</h2>
<ol start="10">
<li>
<h3>Use correct file- and directory permissions</h3>
<p> Avoid 777 of course. It seems this can&#8217;t be repeated enough times though. Extensions like suPHP will take care of setting proper permissions, so talk to your host and make sure they support it.</p>
<p>This will also make the need for the Joomla FTP-layer redundant, so you won&#8217;t neet to use your FTP username and password anywhere.</li>
<li>
<h3>Uninstall stuff you don&#8217;t need</h3>
<p> Brian Teeman has a saying: &#8220;<a href="http://brian.teeman.net/joomla-gps/joomla-hidden-secrets-presentation-at-joomladaysnl.html">Nothing appears on my website that I didn&#8217;t put there</a>&#8220;. Uninstall core components, modules, plugins, templates and other extensions that you&#8217;re not using, including templates and even images. Extensions on your website are all potential security liabilities, either because they add security holes or because they help attackers identify potential security holes. </p>
<p>Observe for instance that installing the <a href="http://joomlacontenteditor.net">JCE WYSIWYG editor</a> will also install TinyMCE, as it is bundled with JCE. Joomla comes with TinyMCE installed as it&#8217;s default editor, so then you&#8217;ll have two TinyMCE installations.</p>
<p>Some core stuff can&#8217;t be uninstalled through the normal uninstaller. This is because they are marked as &#8220;core&#8221; elements in the database. In the components, modules and plugins database tables, there are fields called &#8220;core&#8221; which is set to 1 for these extensions. Change this value to 0 to make them possible to uninstall.
</li>
<li>
<h3>Global configuration setup</h3>
<ol style="list-style:upper-latin">
<li>
<h4>Disable registration/login</h4>
<p>If you don&#8217;t want people to register and/or login on the frontend, make sure you disable the functionality.</li>
<li>
<h4>Disable XML-RPC</h4>
<p>Disable the XML-RPC-server if you don&#8217;t need it.</li>
<li>
<h4>Replace default Joomla meta information with your own data</h4>
<p>Make sure you replace, or at least replace, the default metadata. These will show up in your sourcecode and in Google.</li>
<li>
<h4>Use SEF urls</h4>
<p>Regular URLs <a href="http://forum.joomla.org/viewtopic.php?f=432&amp;t=391251">gives away the fact that Joomla is running your system</a>. But then again, so can a lot of other things. Like for instance a template graphic, a static file, a code structure. Changing from regular to SEF URLs won&#8217;t render the regular URLs useless either, so this is not a very strong security measure. Make sure you also enable the .htaccess-file, see below.</li>
<li>
<h4>Move logs and cache outside the site root</h4>
<p>Change the log and cache paths in the administrator to a folder outside the site root so that they can&#8217;t be accessed through a web browser, or protect the folders in some other way.</li>
</ol>
</li>
<li>
<h3>Remove generator information</h3>
<p><a href="http://forum.joomla.org/viewtopic.php?f=432&amp;t=391251">Remove the generator tag</a> from the head-section of your website.</li>
<li>
<h3>Delete the default user account</h3>
<p> The userid 62 and the username &#8220;admin&#8221; represents a weakness, but there&#8217;s no easy way to replace these during installation. In the administration, the easiest thing you can do is to add a new super administrator, log in as the new super administrator, then demote the admin user to a lower usergroup and then delete the user all together. As our greek friend <a href="http://twitter.com/nikosdion">@nikosdion</a> demonstrates, you can also <a href="http://magazine.joomla.org/topics/item/148-62-reasons-to-fire-your-super-admin">fix this and add users below id 62 with some easy SQL</a>.</p>
<p>Here&#8217;s some quick SQL to help you change the user id and username of the default account right after installation:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="sql"><pre class="de1"><span class="co1">-- Change 3 in both queries with the userid you want</span>
<span class="co1">-- Change jos_ with your own db prefix</span>
<span class="co1">-- Change yourusername with your new username</span>
<span class="kw1">UPDATE</span> jos_users <span class="kw1">SET</span> id<span class="sy0">=</span><span class="nu0">3</span><span class="sy0">,</span> username<span class="sy0">=</span><span class="st0">'yourusername'</span> <span class="kw1">WHERE</span> id<span class="sy0">=</span><span class="nu0">62</span>;
<span class="kw1">UPDATE</span> jos_core_acl_aro <span class="kw1">SET</span> <span class="kw1">VALUE</span><span class="sy0">=</span><span class="nu0">3</span> <span class="kw1">WHERE</span> <span class="kw1">VALUE</span><span class="sy0">=</span><span class="nu0">62</span>;</pre></div></div></div></div></div></div></div>


</li>
<li>
<h3>Enable the .htaccess-file</h3>
<p> The default .htaccess-file has some basic security built in. In Joomla versions earlier than 1.5.15, you should also make sure <a href="http://forum.joomla.org/viewtopic.php?p=1788498#p1788498">it restricts access to critical files</a>. In versions newer than 1.5.15 (1.5.20 is the latest version at the time this writing), you still have to uncomment parts of the .htaccess-file to activate this security measure.&nbsp;</li>
<li>
<h3>Enhance the .htaccess-file</h3>
<p> Nicholas K. Dionysopoulos (that&#8217;s <a href="http://twitter.com/nikosdion">@nikosdion</a> in twitterish) also has a nice <a href="http://snipt.net/nikosdion/the-master-htaccess/">Master .htaccess-file</a> with lots of other goodies included, that&#8217;s really worth a peek. For instance: Restrict directory listings, force https on certain pages, blocking of some common exploits, file injection protection, fingerprint attack blocking, and more.</li>
<li>
<h3>Encrypt communication, or at least the login</h3>
<p>A nice <a href="http://brian.teeman.net/joomla-gps/protect-joomla-passwords-on-public-wifi-networks.html">article by Herman Peeren</a> highlights the dangers of not logging in to your site with SSL, and suggests that if you can&#8217;t set up SSL you at least look into an extension called <a href="http://extensions.joomla.org/extensions/access-a-security/site-security/11519">Encrypt configuration</a>.
</li>
<li>
<h3>Make fingerprinting your site harder</h3>
<p>One of the easiest ways for an attacker to decide if your site is a potential Joomla! target is to perform a rudimentary visual fingerprinting. Both Joomla! and PHP comes with many static resources, special features and even easter eggs that can make it easy to identify what software you&#8217;re using, and what versions they are.</p>
<p>There is a great post in the October 2010 Joomla Community Magazine about this: &#8220;<a href="http://magazine.joomla.org/issues/Issue-Oct-2010/item/214-only-a-ninja-can-kill-another-ninja">Only a ninja can kill another ninja</a>&#8220;, by <a href="http://twitter.com/nikosdion/">@nikosdion</a>.
</li>
<li>
<h3>Choose your extensions wisely</h3>
<ol>
<li>
<h4>Avoid extensions with encrypted sourcecode</h4>
<p> You can&#8217;t fix bugs in encrypted sourcecode yourself, and you&#8217;ll be left at the mercy of the extension producer should something bad surface. This is mostly a personal preference of mine, as I like probing around in people&#8217;s code both to learn and to get a general feeling for the actual quality of the software I&#8217;m running.</li>
<li>
<h4>Avoid dead extensions</h4>
<p>If a extension&#8217;s homepage is returning a 404 error, or hasn&#8217;t been updated in ages, it&#8217;s a good indicator that you should check out if this extension is still being maintained or not, before you decide to install it.</li>
<li>
<h4>Avoid legacy extensions</h4>
<p> Stick to extensions with fresh 1.5 compatible code. Joomla 1.0&#8242;s EOL has passed now, over a year ago, time to move on.</li>
</ol>
</li>
<li>
<h3>Add extra layers of security</h3>
<ol>
<li>
<h4>Protect /administrator with extra measures</h4>
<p> You could require an extra password to access /administrator, or even restrict access to certain IP addresses. Some security plugins, like jSecure can help you accomplish stuff like this too. (<a href="http://magazine.joomla.org/topics/item/66-things-to-do-before-your-site-gets-hacked">thanks to @nikosdion again</a>)</li>
<li>
<h4>Consider installing security extensions</h4>
<p> Lots of opportunities on the JED in the categories <a href="http://extensions.joomla.org/extensions/access-a-security/site-security/site-protection">site protection</a>, <a href="http://extensions.joomla.org/extensions/access-a-security/site-security/site-monitoring">site monitoring</a> and <a href="http://extensions.joomla.org/extensions/access-a-security/site-security/login-protection">login protection</a>. Many of these will help you with the items in this list.</li>
<li>
<h4>Monitor your site for unwanted changes</h4>
<p>Lots of tools can be used here, for example there is a Windows tool out there called Akeeba SiteDiff, which you can use with Akeeba Backup, and which will compare the state of your site with the last known good state. <a href="http://www.dionysopoulos.me/blog/proactive-security-is-sensible-security">Read more about Akeeba SiteDiff</a>.
</li>
<li>
<h4>Add a custom ACL solution</h4>
<p> Joomla 1.5&#8242;s default ACL is not very restrictive, and you may be giving out more access privileges than you&#8217;d like. Brian Teeman has <a href="http://brian.teeman.net/joomla-gps/joomla-15-acl-explained.html" id="x_oz" title="a nice table showing who gets to do what exactly">a nice table showing who gets to do what exactly</a>. Consider adding a <a href="http://extensions.joomla.org/extensions/access-a-security/backend-a-full-access-control">custom ACL solution</a> for better access control.</li>
</ol>
</li>
<li>
<h3>Avoid exposing information</h3>
<p> Disable the display of errors on live sites, so that system paths and server information is not shown. Set display_errors to 0 in a local php.ini for instance, or use <a href="http://www.electrictoolbox.com/set-php-config-options-apache-htaccess-file/" id="qbgb" title="php_value in a .htaccess-file">php_value in a .htaccess-file</a>.</li>
<li>
<h3>Don&#8217;t send out username/password in plain text e-mails</h3>
<p>Sending a plain e-mail is like sending a postcard; it&#8217;s not wise to include anything sensitive in it. Joomla does this by default (!) each time you add a new user to your users list, or when a user signs up. </p>
<p>One way to avoid this is to override the language files; the text that goes out in the account creating confirmation e-mails is located in the language file, so this can be tweaked to not include the password. </p>
<p>In Joomla 1.6 you can also override a single language string without having to create a whole language pack, which makes this easier. There is also a plugin for 1.5 called <a href="http://extensions.joomla.org/extensions/languages/language-edition/13147">Translation Override</a>, which may prove to be useful for this purpose. (thanks to <a href="http://twitter.com/jlleblanc/status/24868684341">@jlleblanc</a>, <a href="http://twitter.com/nikosdion/status/24868750005">@nikosdion</a> and <a href="http://twitter.com/ot2sen/status/24871628779">@ot2sen</a> for the tips)
</li>
</ol>
<p><a name="running_the_website"></a><br />
<h2>Running the website</h2>
<ol start="23">
<li>
<h3>Stay updated</h3>
<p>There&#8217;s one newsfeed for <a href="http://feeds.joomla.org/JoomlaSecurityNews">Joomla Security News</a> and one <a href="http://feeds.joomla.org/JoomlaSecurityVulnerableExtensions">feed for news about vulnerable extensions</a>.</p>
<p>You should use the information to avoid insecure extension, because you can bet that those looking to hack your website are also keeping up to date with news on new vulnerabilities. &#8211; Read the result of Brian Teeman&#8217;s &#8220;<a href="http://docs.joomla.org/Investigation_of_exploits">Investigation of Exploits</a>&#8221; from August 2010. &#8211; Read the <a href="http://docs.joomla.org/Vulnerable_Extensions_List">vulnerable extensions list</a> in the docs wiki, and subscribe to <a href="http://feeds.joomla.org/JoomlaSecurityVulnerableExtensions">it&#8217;s feed</a>. </p>
<p>Note that you can also subscribe to changes on a wiki page like the one above, to be notified whenever it changes. If you go to the <a href="http://docs.joomla.org/Vulnerable_Extensions_List">vulnerable extensions list</a> and register an account and log in, you will get a button in the top menu that allows you to subscribe to changes on that page.</li>
<li>
<h3>Install security patches immediately</h3>
<p> Pay attention to mailing lists announcing insecure extensions and updates to extensions you&#8217;re using, including Joomla itself of course.</li>
<li>
<h3>Backup your site regularly</h3>
<p> If your server host does not do backups for you, you could <a href="http://www.opensourcesupportdesk.com/blog/80-joomla-component/393-how-to-backup-your-joomla-site-to-the-cloud">backup your site to the cloud</a>, or make good use of a <a href="http://extensions.joomla.org/extensions/access-a-security/site-security/backup">backup extension</a>.</p>
<p>Make sure to test that the backup works and always store the backup off-site.</li>
</ol>
<p><a name="developer_checklist"></a><br />
<h2>Developer&#8217;s checklist</h2>
<ol start="26">
<li>
<h3>Use an IDE</h3>
<p>IDEs can help considerably with code quality, development and testing.</li>
<li>
<h3>Use a versioning system</h3>
<p> Stuff like SVN and Git will be a lifesaver the day something is hacked or modified without your knowledge, or goes to hell in another way. It also makes it easier to maintain and roll out different versions of your software. Use versioning even if you&#8217;re the only one doing development, it&#8217;s well worth it.</li>
<li>
<h3>Test locally, deploy globally</h3>
<p> Run different configurations for your test sites and live sites: Stuff that gives away information should never be done where it&#8217;s visible to the public, in particular debugging. Errors should not be shown on a live site, especially not those who disclose paths or system information. As an extensions developer though, all you can do here is probably just advise your customers. This type of setting has to be done on the server.</li>
<li>
<h3>Use CSRF-protection</h3>
<p><a href="http://docs.joomla.org/How_to_add_CSRF_anti-spoofing_to_forms">http://docs.joomla.org/How_to_add_CSRF_anti-spoofing_to_forms</a></li>
<li>
<h3>Don&#8217;t chmod files or folders to 777!</h3>
<p> Not only is this a bad idea security wise, it also tells people reading your code that you&#8217;re lazy at best, and furthermore that you don&#8217;t know what you&#8217;re doing.</li>
<li>
<h3>Filter data</h3>
<p> Filter data the user inputs and escape outputting of user-provided content, which is especially useful for preventing SQL injection and XSS attacks. <a href="http://docs.joomla.org/Tutorial:How_to_make_your_Joomla_addon_more_secure_WIP">Read more about this and see examples</a>.</li>
<li>
<h3>Keep your codebase small</h3>
<p> Reuse previously road-tested code where you can, and stay DRY (Don&#8217;t Repeat Yourself). Less code equals less potential security risks and less code maintenance costs for you.</li>
<li>
<h3>Use Nooku Framework</h3>
<p> If you&#8217;re creating a Joomla extension, you should consider using <a href="http://nooku.org">Nooku Framework</a>, which reduces your codebase with around 80% and does a lot of things automatically, where you in Joomla would have to write code manually. Directly related to security, Nooku gives you automatic CSRF protection (automatic form tokens and token control), automatic data filtering and soon also automatic output escaping by default. </li>
<li>
<h3>No executable code in class files</h3>
<p> In your class files, stick to one class pr file and leave no executable code.</li>
<li>
<h3>Use _JEXEC</h3>
<p> use a _JEXEC test in files, especially templates or files with executable code, to make sure the file is loaded from within the application. Files with just a PHP class in them do not need this.</li>
<li>
<h3>Keep names and versions hidden</h3>
<p> Don&#8217;t display extension names and versions in the code or on your site. &#8220;Powered by Superapp version 1.5&#8243; on page footers that use your application, combined with a listing of Superapp version 1.5 being vulnerable on the list of vulnerable extensions, makes your clients easy targets. At least don&#8217;t display this info until Joomla gets a better upgrading system so that people can update outdated extensions in a painless manner. </p>
<p>Worth reading in this context: <a href="http://googlewebmastercentral.blogspot.com/2009/11/new-software-version-notifications-for.html">New Software Notifications in Google Webmaster Tools</a>. </li>
</ol>
<p><a name="if_you_get_hacked"></a><br />
<h2>What to do if your site gets hacked</h2>
<ol start="37">
<li>
<h3>Take your site offline</h3>
<p>If malicious code has been injected into your site, you&#8217;d not want others to get their computers infected or compromised. For tougher cases: Add an IP filter so that only your IP-address can access your site while your fixing it.</p>
<h4>Remember: Offline does not mean unavailable</h4>
<p>Setting a website in maintenance mode is merely a visual thing that indeed will execute all plugins and component requests, but merely render the offline template. So if someone has found a loophole to get into your site, and you want to shut them out while you fix the problem, setting the site in maintenance mode will not help you.</p>
<p>Nicholas Dionysopoulos published <a href="http://www.dionysopoulos.me/blog/how-offline-is-joomla-offline-mode">a blog post</a> with information on this subject which is useful. He outlines one possible way around this issue, where he uses .htaccess to redirect all request to offline.html directly, bypassing Joomla completely. This means you have to have an offline-page of pure HTML to serve too of course. He also adds an exception so that you yourself can access the Joomla page from a specific IP-address. </p>
<p>Read <a href="http://www.dionysopoulos.me/blog/how-offline-is-joomla-offline-mode">the original blog post</a> for a more in-depth explenation and code sample.
</li>
<li>
<h3>Find other people with similar errors</h3>
<p>First thing to do would be to <a href="http://forum.joomla.org/search.php">search the Joomla forums</a> or search the web to try to find scenarios similar or identical to yours. This can save you a lot of time in the recovery phase, since you may benefit from other people&#8217;s findings.
</li>
<li>
<h3>Make sure your computers haven&#8217;t been compromised</h3>
<p>Malicious software on any computer with is used for accessing the site or it&#8217;s FTP accounts for instance, can be used by an intruder to gain access to your online user accounts. Use a scanner software to scan for malware, trojans, viruses, spyware, etc. A list of available software packages can be found in the Joomla documentation under &#8220;Local security&#8221;.
</li>
<li>
<h3>Verify that you have the latest versions</h3>
<p>Check that you have the latest Joomla version and the latest versions of your extensions, and that you&#8217;re not using any extension versions with known vulnerabilities. See lists of vulnerable extensions on the <a href="http://docs.joomla.org/Vulnerable_Extensions_List">Joomla documentation wiki</a> and in the <a href="http://feeds.joomla.org/JoomlaSecurityVulnerableExtensions">Joomla security newsfeed</a>.
</li>
<li>
<h3>Locate modified files</h3>
<p>Log in to your server and use the find command to find out which files have been changed recently.</p>
<p>This command will list all files in the current folder where the <strong>file modification time (mtime) is less than three days old</strong>:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="bash"><pre class="de1"><span class="kw2">find</span> . <span class="re5">-mtime</span> <span class="re5">-3</span></pre></div></div></div></div></div></div></div>


<p>This command will list all files in the current folder where the <strong>last change of file status (ctime) happened less than three days ago</strong>:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="bash"><pre class="de1"><span class="kw2">find</span> . <span class="re5">-ctime</span> <span class="re5">-3</span></pre></div></div></div></div></div></div></div>


<p>This command will list all <strong>files changed at least one day ago but less than three days ago</strong>:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="bash"><pre class="de1"><span class="kw2">find</span> . <span class="re5">-ctime</span> +<span class="nu0">1</span> <span class="re5">-a</span> <span class="re5">-ctime</span> <span class="re5">-3</span></pre></div></div></div></div></div></div></div>


</li>
<li>
<h3>Find out what&#8217;s changed on your server</h3>
<p>If files have been modified on your server, or files have been uploaded for instance, you can check the timestamps on those files to find out when the attacker was on your site. This is typical in the case of sites being <a href="http://en.wikipedia.org/wiki/Website_defacement">defaced</a> or malicious code being injected somewhere.  Most of the time, the attacker will have gained access to your site shortly before modifying or uploading files to it. By checking your access logs for the period around that time, you may find some clues as to how the attacker gained access and which IP-address the attack came from, thus enabling you to track down things more easily in the logs.</p>
<p>You can also try searching for suspicious POST requests made to for instance non-form addresses on your site. </p>
<p>Use any information gained from this to block out further attacks and patch weak spots in your system.
</li>
<li>
<h3>Check your crontab/task scheduler</h3>
<p>Check your crontab and make sure there are no things in there that you didn&#8217;t put there yourself. If you can&#8217;t access your crontab or don&#8217;t know how to, ask your hosting provider for help.
</li>
<li>
<h3>Report the attack to your host</h3>
<p>Get your host to help you flush out the problems and make sure the attacker has not left any hidden backdoors to make it easy for him to regain access to your site.
</li>
<li>
<h3>Change your passwords</h3>
<p>Change passwords and, if you can, usernames to all access points to your site: MySQL databases, FTP users, administrators, SSH accounts, control panel logins, etc. Use <a href="http://www.torkiljohnsen.com/2010/08/18/how-to-create%E2%80%94and-remember%E2%80%94a-different-password-for-every-single-login/">strong passwords</a>!
</li>
<li>
<h3>Restore a working backup, or reinstall completely</h3>
<p>Wipe your server clean and roll back to a known, safe backup. Make sure all security holes have been patched before you reopen the site. You should also consider deleting the entire installation and just reinstall Joomla and your extensions from scratch, so that you are certain not to include any backdoors a hacker may have left behind prior to the attack.
</li>
<li>
<h3>Report security issues you may find</h3>
<p>If you find soft spots in Joomla or any Joomla Extensions, report them on the <a href="http://forum.joomla.org/viewforum.php?f=432">security forum</a>, but without outlining to the public how to hack one million Joomla sites in 10 seconds. Also contact extension developers directly to give them a chance to produce a patch for their users. </p>
<p>When you report problems on the security forum, use the <a href="http://forum.joomla.org/viewtopic.php?f=428&#038;t=272481">post assistant tool</a> to make sure you include all the required information so that people are able to help you properly.
</li>
<li>
<h3>Official tips lists</h3>
<ul>
<li><a href="http://forum.joomla.org/viewtopic.php?f=432&#038;t=335090">Has your site been compromised? Read this</a>.</li>
<li><a href="http://docs.joomla.org/Security_Checklist_7">Go through this Security Checklist</a></li>
<li><a href="http://forum.joomla.org/viewtopic.php?p=1988191#p1988191">Read this before asking security support questions</a></li>
</ul>
</li>
</ol>
<p><a name="resources"></a><br />
<h2>Further reading, other resources</h2>
<ol start="49">
<li>
<h3>Read Nicholas&#8217; blog</h3>
<p><a href="http://www.dionysopoulos.me/" title="Nicholas K. Dionysopoulos">Nicholas K. Dionysopoulos&#8217; blog</a> is currently, by far, the best source of new information on this subject.
</li>
<li>
<h3>Follow Jeff Channel (<a href="http://twitter.com/jeffchannell">@jeffchannel</a>)</h3>
<p>Jeff has found several security holes both in the Joomla core and in well-known Joomla extensions. He tweets regularly about security, and you could probably also hire him to do a security audit of your extension.
</li>
<li>
<h3>Joomla security forum</h3>
<p>Discuss at <a href="http://forum.joomla.org/viewforum.php?f=432">the Joomla 1.5 security forum</a>.</li>
<li>
<h3>Security checklist</h3>
<p><a href="http://docs.joomla.org/Category:Security_Checklist">Joomla official security checklist</a></li>
</ol>
<p><a name="acknowledgements"></a><br />
<h2>Acknowledgements</h2>
<p>Thanks to <a href="http://brian.teeman.net" id="c3u." title="Brian Teeman">Brian Teeman</a> for valuable input and to <a href="http://www.dionysopoulos.me/" id="p7_x" title="Nicholas K. Dionysopoulos">Nicholas K. Dionysopoulos</a> for his numerous articles on this subject!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.torkiljohnsen.com/2010/09/18/collection-of-joomla-security-tips/feed/</wfw:commentRss>
		<slash:comments>26</slash:comments>
		</item>
		<item>
		<title>Should I care about SEF URLs anymore?</title>
		<link>http://www.torkiljohnsen.com/2010/09/17/should-i-care-about-sef-urls-anymore/</link>
		<comments>http://www.torkiljohnsen.com/2010/09/17/should-i-care-about-sef-urls-anymore/#comments</comments>
		<pubDate>Fri, 17 Sep 2010 20:39:45 +0000</pubDate>
		<dc:creator>tj</dc:creator>
				<category><![CDATA[Marketing]]></category>
		<category><![CDATA[Search engines]]></category>

		<guid isPermaLink="false">http://www.torkiljohnsen.com/?p=501</guid>
		<description><![CDATA[Exchanged opinions with Peter van Westen and Nicholas K. Dionysopoulos on Twitter, and long story short; they consider SEF URLs to be something that neither people nor Google care about anymore. I thought I disagreed at first, but then I realized I should not have an opinion on this, I should have facts. So here [...]]]></description>
			<content:encoded><![CDATA[<p>Exchanged opinions with <a href="http://twitter.com/nonumber_nl/status/24744961275">Peter van Westen</a> and <a href="http://twitter.com/nikosdion/status/24741887030">Nicholas K. Dionysopoulos</a> on Twitter, and long story short; they consider SEF URLs to be something that neither people nor Google care about anymore. I thought I disagreed at first, but then I realized I should not have an opinion on this, I should have facts. So here is my research.</p>
<p><span id="more-501"></span></p>
<h2>Google says</h2>
<p>I started with looking up <a href="http://www.google.com/support/webmasters/bin/answer.py?hl=en&#038;answer=35769#2">Google&#8217;s Webmaster Guidelines</a>, which was updated as late as 9/8/2010 according to the page footer, and I found the following relevant statements:</p>
<blockquote><p>If you decide to use dynamic pages (i.e., the URL contains a &#8220;?&#8221; character), be aware that not every search engine spider crawls dynamic pages as well as static pages. It helps to keep the parameters short and the number of them few.</p></blockquote>
<p>My conclusion: Static pages (without the ?) are more likely to be crawled by most search engine spiders. The more parameters you have in the query string, the more problems you can get. Google has not written off the value of static URLs just yet. </p>
<blockquote><p>Allow search bots to crawl your sites without session IDs or arguments that track their path through the site. These techniques are useful for tracking individual user behavior, but the access pattern of bots is entirely different. Using these techniques may result in incomplete indexing of your site, as bots may not be able to eliminate URLs that look different but actually point to the same page.</p></blockquote>
<p>My conclusion: Dynamic URLs, like static ones, should describe what&#8217;s on the page, nothing more. ?category=15&#038;id=98 is perfectly fine.</p>
<p><strong>Reading from the official blog post from Google</strong> with the spot-on title &#8220;<a href="http://googlewebmastercentral.blogspot.com/2008/09/dynamic-urls-vs-static-urls.html">Dynamic URLs vs. static URLs</a>&#8220;, I conclude that Google&#8217;s opinion is this: </p>
<p>Don&#8217;t rewrite, you <em>can</em> do more harm than good, since rewritten URLs can be harder to maintain.</p>
<h2>Experts say</h2>
<p>Experts? Who are these so-called experts? Well, I googled some topics and clicked the top topics basically. I figure that those who manage to stay in the top 10 on Google for searches on SEF URLs are probably pretty good at this search engine stuff.</p>
<p><strong>So here are some opinions I&#8217;ve come across</strong> (on sites that all seem to be using static URLs):</p>
<p>Opinions lifted from <a href="http://www.seobook.com/do-you-need-use-url-rewriting">seobook.com</a>:</p>
<ol>
<li>People are more likely to click on SEF URLs. Looks like an assumption, but <a href="http://googlewebmastercentral.blogspot.com/2008/09/dynamic-urls-vs-static-urls.html">Google actually backs this up</a>.</li>
<li>The URLs will provide better anchor text if people use the URLs as the link anchor text.</li>
<li>A transition to a new CMS can be easier with static URLs</li>
<li>Dynamic URLs don&#8217;t work well for offline marketing.</li>
<li>Dynamic URLs can be used for web application fingerprinting.</li>
<li>Google&#8217;s recommendation on avoiding rewriting URLs is directed mostly at less savvy webmasters, hoping that they think before they risk messing up their website at an <a href="http://twitter.com/nikosdion/status/24744152067">attempt at installing and configuring a SEF URL rewriting module of some sort</a>.</li>
</ol>
<p><a href="http://www.seomoz.org/blog/dynamic-urls-vs-static-urls-the-best-practice-for-seo-is-still-clear">Rand Fishkin also backs up that last opinion</a>, basically saying you must remember that Google is approaching this from a crawling standpoint, not a marketing standpoint. He also goes on to point out some pros and cons of static and dynamic URLs, and while this is written way back in 2008 he brings up some good points:</p>
<blockquote><h4>Pros of Dynamic URLs</h4>
<ul>
<li>Umm&#8230; they&#8217;re usually longer?</li>
<li>Google (1 of the 4 major search engines) says they can effectively crawl and index them</li>
</ul>
<h4>Cons of Dynamic URLs</h4>
<ul>
<li>Lower click-through rate in the search results, in emails, and on forums/blogs where they&#8217;re cut and pasted</li>
<li>A greater chance of cutting off the end of the URL, resulting in a 404 or other error when copying/pasting</li>
<li>Lower keyword relevance and keyword prominence</li>
<li>Nearly impossible to write down manually and share on a business card or read over the phone to a person</li>
<li>Challenging (if not impossible) to manually remember</li>
<li>Does not typically create an accurate expectation of what the user will see prior to reaching the page</li>
<li>Not usable in branding or print campaigns</li>
<li>Won&#8217;t typically carry optimized anchor text when used as the link text (which happens frequently due to copying &#038; pasting)</li>
</ul>
<h4>Pros of Static URLs (mostly the opposites of the above)</h4>
<ul>
<li>Higher click-through rates in the SERPs, emails, web pages, etc.</li>
<li>Higher keyword prominence and relevancy</li>
<li>Easier to copy, paste and share on or offline</li>
<li>Easy to remember and thus, usable in branding and offline media</li>
<li>Creates an accurate expectation from users of what they&#8217;re about to see on the page</li>
<li>Can be made to contain good anchor text to help the page rank higher when linked-to directly in URL format</li>
<li>All 4 of the major search engines (and plenty of minor engines) generally handle static URLs more easily than dynamic ones, particularly if there are multiple parameters</li>
</ul>
<h4>Cons of Statics URLs</h4>
<p>You might mess up the rewriting process, in which case your users and search engines will struggle to find content properly on your site.</p></blockquote>
<p>This is however a field in which things change rapidly, like in everything else web-related. </p>
<p>I&#8217;ll conclude for now with still thinking that SEF URLs will help SEO efforts, if you care about that. If you don&#8217;t, people will probably still find your content. </p>
<p>I don&#8217;t think it&#8217;s the most important part of SEO though. Everything starts at producing quality content. If you don&#8217;t have the quality content, working with SEF URLs will probably be a waste of time. If you&#8217;re using Joomla or WordPress, or basically any modern web framework or CMS, you&#8217;ll probably get SEF URLs for free, included in the package. In this context I see nothing wrong with just activating the feature, as it <em>will</em> give you some extra benefits.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.torkiljohnsen.com/2010/09/17/should-i-care-about-sef-urls-anymore/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 1.227 seconds -->

