<?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>thinkMoult &#187; PHP</title>
	<atom:link href="http://thinkmoult.com/tag/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://thinkmoult.com</link>
	<description>Seriously who ever reads this description.</description>
	<lastBuildDate>Sun, 08 Apr 2012 03:22:49 +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>Presenting the Nagger</title>
		<link>http://thinkmoult.com/2011/01/22/presenting-the-nagger/</link>
		<comments>http://thinkmoult.com/2011/01/22/presenting-the-nagger/#comments</comments>
		<pubDate>Fri, 21 Jan 2011 20:02:08 +0000</pubDate>
		<dc:creator>Dion Moult</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[batch]]></category>
		<category><![CDATA[gd]]></category>
		<category><![CDATA[nag]]></category>
		<category><![CDATA[nagger]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[sync]]></category>
		<category><![CDATA[wallpaper]]></category>

		<guid isPermaLink="false">http://thinkmoult.com/2011/01/22/presenting-the-nagger/</guid>
		<description><![CDATA[Over Christmas one of my more humourous gifts to my parents was to allow them to remotely nag each other electronically. Since my dad is often overseas, this actually has some practical use. The idea was to create a remotely synchronised dynamic wallpaper with text that could be set by another person remotely. Person A [...]
No related posts.]]></description>
			<content:encoded><![CDATA[<p>Over Christmas one of my more humourous gifts to my parents was to allow them to remotely nag each other electronically. Since my dad is often overseas, this actually has some practical use.</p>
<p>The idea was to create a remotely synchronised dynamic wallpaper with text that could be set by another person remotely. Person A would type in some text, a wallpaper with the text formatted would be generated, Person B&#8217;s computer would detect that there is an update, download the wallpaper and set it immediately. (I originally wanted to make a pop up message, but realised that having &quot;Go and exercise!&quot; pop up during a powerpoint presentation with your boss wasn&#8217;t the best thing)</p>
<p>The system would operate as such: I would create a html form on my webserver to allow somebody to type in text. PHP would take the text and use GD to generate a .jpg file of an image with the text overlayed on top. Batch file on Windows computer would download the .jpg file (either on startup, or via cronw) via URL2FILE. Batch file will call imagemagick installed on the Windows computer to convert .jpg to .bmp because apparently that&#8217;s what Windows likes for wallpaper formats and converting on the server would mean a ultra big file download. Finally, batch file will tweak the registry to change the wallpaper and &quot;refresh&quot; it such that it changes immediately.</p>
<p>Here&#8217;s an example :)</p>
<p><img src="http://thinkmoult.com/wp-content/uploads/2011/01/wallpaper.jpg" /></p>
<p>PHP code:</p>
<p><code>&lt;?php<br />if (isset($_POST['submit']) &amp;&amp; isset($_POST['nag']) &amp;&amp; !empty($_POST['nag'])) {<br />$width = 1280;<br />$height = 800;<br />$imgname = &quot;wallpaper_blank.jpg&quot;; # The empty blue background template<br />$im = imagecreatefromjpeg ($imgname);<br />$text = $_POST['nag'];<br />$textcolor = ImageColorAllocate($im, 255, 255, 255);<br />$font = 20;<br />$font_width = ImageFontWidth($font);<br />$font_height = ImageFontHeight($font);<br />$font_width = 10;<br />$text_width = $font_width * strlen($text);<br />// Position to align in center<br />$position_center = ceil(($width - $text_width) / 2);<br />$text_height = $font_height;<br />// Position to align in abs middle<br />$position_middle = ceil(($height - $text_height) / 2);<br />imagettftext ($im, 15, 0, $position_center, $position_middle, $textcolor,<br />'/path/to/ttf/fontfile/AllOverAgainAllCaps.ttf', $text); # We're offsetting this a little to give space for desktop icons<br />Imagejpeg($im, '/path/to/final/image/wallpaper.jpg', 100);<br />chmod('/path/to/final/wallpaper.jpg', 0644); # Ensure we can download it (depending on server setup)<br />echo 'Nag done!';<br />} else {<br />echo '&lt;form action=&quot;&quot; method=&quot;post&quot;&gt;';<br />echo '&lt;textarea name=&quot;nag&quot; rows=&quot;10&quot; cols=&quot;50&quot;&gt;&lt;/textarea&gt;&lt;br /&gt;';<br />echo '&lt;input type=&quot;submit&quot; name=&quot;submit&quot; value=&quot;Nag!&quot;&gt;';<br />echo '&lt;/form&gt;';<br />} </code> </p>
<p>Batchfile code:</p>
<p><code>C:\path\to\URL2FILE.EXE http://mysite.com/wallpaper.jpg C:\path\to\save\wallpaper.jpg<br />C:\path\to\imagemagick\convert.exe C:\path\to\save\wallpaper.jpg C:\path\to\save\wallpaper.bmp<br />REG ADD &quot;HKCU\Control Panel\Desktop&quot; /V Wallpaper /T REG_SZ /F /D &quot;C:\path\to\save\wallpaper.bmp&quot;<br />REG ADD &quot;HKCU\Control Panel\Desktop&quot; /V WallpaperStyle /T REG_SZ /F /D 2<br />REG ADD &quot;HKCU\Control Panel\Desktop&quot; /V TileWallpaper /T REG_SZ /F /D 0<br />%SystemRoot%\System32\RUNDLL32.EXE user32.dll, UpdatePerUserSystemParameters </code> </p>
<p>I thought it was cute, parents loved it.</p>
<p>P.S. If anybody knows a sane wait to input code into WordPress/Blogilo and have it immediately embedded in &lt;code&gt; tags as well as not lose whitespace, give me a poke.</p>
<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://thinkmoult.com/2011/01/22/presenting-the-nagger/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>WIPUP 27.06.10a released!</title>
		<link>http://thinkmoult.com/2010/06/27/wipup-27-06-10a-released/</link>
		<comments>http://thinkmoult.com/2010/06/27/wipup-27-06-10a-released/#comments</comments>
		<pubDate>Sat, 26 Jun 2010 17:04:46 +0000</pubDate>
		<dc:creator>Dion Moult</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[27.06.10]]></category>
		<category><![CDATA[alpha]]></category>
		<category><![CDATA[eadrax]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[open-source]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[release]]></category>
		<category><![CDATA[update]]></category>
		<category><![CDATA[wipup]]></category>

		<guid isPermaLink="false">http://thinkmoult.com/?p=1388</guid>
		<description><![CDATA[It&#8217;s super, it&#8217;s amazing, and it&#8217;s released. It&#8217;s WIPUP 27.06.10a. For the uninitiated, WIPUP is a flexible and easy way for people to share, critique, and track works-in-progresses. To quote some random person, this release truly brings out the &#8220;hey, it&#8217;s like a working site now&#8220;. This release sports super fancy upgrades courtesy of my schedule, [...]
No related posts.]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s super, it&#8217;s amazing, and it&#8217;s released. It&#8217;s WIPUP 27.06.10a. For the uninitiated, <strong>WIPUP is a flexible and easy way for people to share, critique, and track works-in-progresses</strong>.</p>
<p>To quote some random person, this release truly brings out the &#8220;<em>hey, it&#8217;s like a working site now</em>&#8220;. This release sports super fancy upgrades courtesy of my schedule, which is now free from exams and school. Check out the <a href="http://wipup.org/">WIPUP website</a> now, and read the <a href="http://wipup.org/updates/view/122">release notes</a>.</p>
<p style="text-align: center;"><a href="http://wipup.org/updates/view/122"><img class="aligncenter size-full wp-image-1389" title="wipup_release_27_06_10a" src="http://thinkmoult.com/wp-content/uploads/2010/06/wipup_release_27_06_10a.jpg" alt="" width="640" height="256" /></a></p>
<p>Of course it&#8217;s also open-source, so not only do we welcome new users, but developers too! This is hopefully the last &#8220;alpha&#8221; release, so feel free to join.</p>
<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://thinkmoult.com/2010/06/27/wipup-27-06-10a-released/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Plans for E2-Productions.com to turn into a personal cloud?</title>
		<link>http://thinkmoult.com/2010/05/14/plans-for-e2-productions-com-to-turn-into-a-personal-cloud/</link>
		<comments>http://thinkmoult.com/2010/05/14/plans-for-e2-productions-com-to-turn-into-a-personal-cloud/#comments</comments>
		<pubDate>Thu, 13 May 2010 08:40:01 +0000</pubDate>
		<dc:creator>Dion Moult</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[flexibility]]></category>
		<category><![CDATA[freedom]]></category>
		<category><![CDATA[open-source]]></category>
		<category><![CDATA[personal cloud]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[synchronisation]]></category>
		<category><![CDATA[web 2.0]]></category>

		<guid isPermaLink="false">http://thinkmoult.com/2010/05/14/plans-for-e2-productions-com-to-turn-into-a-personal-cloud/</guid>
		<description><![CDATA[Alert! Alert! Buzzword! Yes, before we start, let&#8217;s clear up with what I mean when I say &#34;personal cloud&#34;. A personal cloud is a web-accessable system which centralises the function of common web 2.0 services, which may or may not be social. For those that aren&#8217;t familiar with this jargon, web 2.0 services are those [...]
No related posts.]]></description>
			<content:encoded><![CDATA[<p>Alert! Alert! <a href="http://thinkmoult.com/2010/04/20/bingo-sir/">Buzzword</a>! Yes, before we start, let&#8217;s clear up with what I mean when I say &quot;personal cloud&quot;. <strong>A personal cloud is a web-accessable system which centralises the function of common web 2.0 services, which may or may not be social.</strong> For those that aren&#8217;t familiar with this jargon, web 2.0 services are those such as web email clients like GMail, photo sharing and management sites like Flickr, online radios like Last.FM, and even blogs just like this one. So your personal cloud is a system on your very own website, with a web interface for your very own emails, PIM (calendar, notes, todos), images, music, etc. Note that the social attribute is <em>optional</em>. Clouds do not have to necessarily have automatic synchronisation, nor does it have to have the ability to easily share your data with the public.</p>
<p>A little history first. <a href="http://e2-productions.com">E2-Productions.com</a> used to be the center of attention &#8211; thriving with the latest adolescent community fads such as animation, art and music &quot;portals&quot;. It later saw the rise of the Blender Model Repository, a personal portfolio, several forums (trendy, weren&#8217;t they?), and finally ended with the death of the original animation portal. thinkMoult then emerged somewhere on the Blogspot blogosphere and went on to become a moderately-hacked install of WordPress on the E2 server. E2-Productions had become, and still is now, a dead site.</p>
<p>I&#8217;ve been toying with the idea of turning E2-Productions into a personal cloud for quite some time. It did actually occur at one point. Even though a PHP developer myself, it would take too long to create my very own cloud to implement existing free scripts. In the end I had created a network of individual PHP scripts giving me a web based RSS reader, filebin, imagebin, and a proxy. With the helpful addition of several rsync scripts and sshfs, it was usable and offered all the functionality. However of course it was very hacked together and didn&#8217;t offer the sort of integration I wanted.</p>
<p align="center"><img src="http://thinkmoult.com/wp-content/uploads/2010/05/owncloud-logo.png" /></p>
<p>Today I decided to look into other cloud services. One currently in development is <a href="http://owncloud.org/index.php/Main_Page">ownCloud</a> by Frank Karlitschek, the guy resonsible behind the <a href="http://opendesktop.org/help/about.php?PHPSESSID=b6c8dc129a3db869c60bfc845f3896db">openDesktop websites</a>. Unfortunately the results were disappointing. Taking into account that it&#8217;s still under construction (and therefore incomplete and buggy), like the openDesktop websites themselves, ownCloud is unfortunately yet another developer service that underestimates usability. Whilst it had some nifty features in the works, it&#8217;s priorities were skewed away from the <em>rightful</em> mentality that <strong><em>design maketh a website, not the function</em></strong>. Further probing into the code revealed some serious problems with the structure of the coding that didn&#8217;t look very well thought out. Needless to say ownCloud is not for me.</p>
<p align="center"><img src="http://thinkmoult.com/wp-content/uploads/2010/05/eyeos-logo.png" /></p>
<p>The other famous personal cloud is the open-source EyeOS. This one goes <em>all the way</em>, completely replicating the desktop interface in the browser. Again, most of the design of EyeOS 1.x, their stable version, approaches the design of the system as a <em>desktop interface</em>. <strong>The canvas of a webpage is not suited for a desktop interface</strong>. They both have strengths and weaknesses and unfortunately most of these uncanny designs don&#8217;t play to the webbrowser&#8217;s strengths. Despite the overblown interface (which excusably is amended quite a bit in their 2.0 unstable version) it&#8217;s quite featureful and its extensibility in terms of developing it yourself is quite attractive. However the lag which accompanies such client-side interactive bloat (and server-side too!) doesn&#8217;t exactly make it the most practical of choices. It&#8217;s definitely worth keeping an eye on, though (excuse the pun).</p>
<p align="center"><img src="http://thinkmoult.com/wp-content/uploads/2010/05/tonido-logo.png" /></p>
<p>Further searching yielded an <em>exemplary</em> system called <a href="http://www.tonido.com/">Tonido</a>. Unfortunately due to its proprietary nature it&#8217;s not for me either. However it does provide a fine example of the potential of a well executed cloud service. This motivated me to reconsider creating a cloud. I began with considering the <em>basic user</em> objectives for the web interface:</p>
<ul>
<li> Ability to dump a file online with a unique private URL, and easily share it via public URL (or a single obfuscated URL).</li>
<li> Private browsing of my files with support for subdirectories.</li>
<li> Browsing of images will be represented in userfriendly thumbnail form.</li>
<li> Browsing of PIM data (vcard, ical) will be parsed and displayed in an appropriate format.</li>
<li> Web-based uploader and/or form of synchronisation technique.</li>
</ul>
<p>You see the &quot;cloud&quot; I had described (in terms of its most basic <em>user-side </em>functionality) as such is pretty much just a smart web-based filebrowser with mini-webapp additions for (mainly) PIM-data. Our latest newcomer to the fad, <a href="https://one.ubuntu.com">Ubuntu One</a>, actually provides these needs very well &#8211; leaving the browser to do what it does best, and the rest to the desktop. However it falls short in a vital area &#8211; proprietariness. This isn&#8217;t a question of evangelism, it&#8217;s more of one of the simple requirements of a <em>personal</em> cloud. If we analyse the 5 basic user-side needs to its roots, we get a shorter list of <em>what actually makes a personal cloud, personal</em>:</p>
<ul>
<li> Fine control of private, limited, and public files.</li>
<li> Convenience &#8211; data should be searchable by tags, and there should be no limit on the filestructure or methods of access.</li>
<li> Timelessness &#8211; data should not be locked into any vendor.</li>
</ul>
<p>The first issue is tackled quite well in existing cloud providers, with probably the best implementation (in my opinion) being Ubuntu One. Convenience is another easily satisfied need, with wonderful tools like rsync, sshfs, and version control software (though again, most providers lock you into their own system, and convenience ends once you leave it). However the key feature that in my eyes hasn&#8217;t yet been solved by any provider is timelessness. Any proprietary client or syncing software is instantly disqualified due to dependency on the vendor. Now, even if the software was completely open and extensible, many so called <em>personal clouds</em> are simply <em>connecting to existing external services</em>. Whilst consistent with the definition of the personal cloud, the service centralises in what is hoped to be seen as the path of least resistance &#8211; that is, only for people actually already using those services. What services am I talking about? Oh, things like Flickr, Google, Facebook and Twitter. Social is a hot topic, but not for everybody. Services don&#8217;t even have to be online &#8211; dependency on, for example Tomboy Notes or Evolution in Ubuntu One qualifies as a dependency and thus means the service is not timeless.</p>
<p>So how is this overcome? Not easily, for sure. I want to propose that the ideal personal cloud be one that focuses simply on file management and synchronisation. It should stop there &#8211; the actual display of files and searching of files should be handled by plugins. Plugins can decide how to properly format an image gallery. Plugins can decide how to display PIM-data. These plugins should be accomodating for the most timeless format ever, plaintext, as well as industry standard formats. The user then only applies the plugins that fits their exact workflow, if necessary writing their own for interpreting their own files. This satisfies the 3 criteria of a <em>personal</em> cloud.</p>
<p>I&#8217;m still coming up with a few plans and extra ideas on how it&#8217;ll be &#8211; but meanwhile I&#8217;ve got exams to get over. If anybody knows something similar that exists, let me know, otherwise this&#8217;ll be a fun project after WIPUP reaches stable.</p>
<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://thinkmoult.com/2010/05/14/plans-for-e2-productions-com-to-turn-into-a-personal-cloud/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Make a category not considered as a post in WordPress</title>
		<link>http://thinkmoult.com/2009/09/24/make-a-category-not-considered-as-a-post-in-wordpress/</link>
		<comments>http://thinkmoult.com/2009/09/24/make-a-category-not-considered-as-a-post-in-wordpress/#comments</comments>
		<pubDate>Thu, 24 Sep 2009 14:25:18 +0000</pubDate>
		<dc:creator>Dion Moult</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Asides]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[category]]></category>
		<category><![CDATA[modification]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[theme]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://thinkmoult.com/?p=1022</guid>
		<description><![CDATA[In other words, how do you make posts that are in a certain category not count towards total page post count in WordPress? A while back I set up Asides on this blog. The problem was that previously I was displaying 5 posts per page. Now with asides it still displayed 5 posts per page, [...]
No related posts.]]></description>
			<content:encoded><![CDATA[<p>In other words, <strong>how do you make posts that are in a certain category not count towards total page post count in WordPress</strong>?</p>
<p><a href="http://thinkmoult.com/2009/09/20/implemented-a-new-asides-feature/">A while back I set up Asides</a> on this blog. The problem was that previously I was displaying 5 posts per page. Now with asides it still displayed 5 posts per page, but as asides are probably one sentence long at most I personally don&#8217;t consider them to be blog posts. This meant that it didn&#8217;t display 5 &#8220;real&#8221; posts per page. So, how do I fix this?</p>
<p><em>Disclaimer: I&#8217;m not experienced in the under-the-hood of WordPress and as a result some of this solution might be hackery. However it works for me, and that&#8217;s what counts.</em></p>
<h3>Problem 1: displaying 5 real posts per page regardless of how many asides there are.<em><br />
</em></h3>
<p>WordPress loops through a series of posts per page and displays them one by one. Initially I thought they would increment a counter, of which I could easily change so that if the post category was in &#8220;asides&#8221;, it will not increment the counter. However there were a couple flaws: 1) There was no counter, or I completely missed one, 2) The database queries sets the LIMITs from the administrator settings right at the very beginning, and 3) pagination will be completely messed up.</p>
<p>The solution was pretty simple, <strong>firstly we set the database query LIMIT to an obscenely large amount &#8211; more posts than we ever think we&#8217;ll need on a page</strong>. This can be done in the administrator panel. Change &#8220;display posts per page&#8221; to a random large value. I chose 15 because it seems pretty realistic that real posts + aside posts &lt; 15 for 99.9% of the time.</p>
<p><strong>The second step is to manually change the criteria for when the loop terminates</strong>. This way it will not actually show 15 posts, but instead <em>up to 15 posts</em>. What we&#8217;ll do is create a new counter, where ever time we display a post that isn&#8217;t an &#8220;aside&#8221;, we increment the counter, until it hits 5 posts (if I wanted 5 real posts per page) &#8211; at which time it&#8217;ll terminate the loop.</p>
<p>This can be done in the<em> wp-includes/query.php</em> page. To begin with we&#8217;ll need a new variable in the class for our counter. So below <code>class WP_Query {</code> we should add:</p>
<p><code>var $counting_up = 0;</code></p>
<p>Just to make sure that <code>$counting_up</code> resets itself as it should, we&#8217;ll add this to the <code>init()</code> function:</p>
<p><code>$this-&gt;counting_up = 0;</code></p>
<p>Now the next step is to modify the <code>the_post()</code> function. When the loop has started and the category is not an aside, we&#8217;ll increment our counter. In this example my aside category ID is category 429. This will be different for you, so you change it. So simply add this to the <code>the_post()</code> function:</p>
<p><code>if ( !in_category(429) &amp;&amp; $this-&gt;current_post != -1 ) {<br />
$this-&gt;counting_up++;<br />
}</code></p>
<p>Now we&#8217;ve got our counter, we&#8217;ll set up the loop to terminate correctly. This can be done in the <code>have_posts()</code> function. Notice this is the <code>have_posts()</code> function inside the WP_Query class, not outside. We can modify our if statement to terminate when our counter hits 4 posts (as the first isn&#8217;t counted &#8211; therefore in effect we&#8217;ll display 5 real posts), and also when we don&#8217;t have a <code>do_not_terminate</code> variable set to the WP_Query. Why this <code>do_not_terminate</code> variable is important is if we ever need to override this, as well as later I&#8217;ll explain when we look at pagination issues. Here is my completed modified if statement:</p>
<p><code>if ($this-&gt;counting_up == 4 &amp;&amp; !$this-&gt;query_vars['do_not_terminate']) {<br />
$this-&gt;in_the_loop = false;<br />
do_action_ref_array('loop_end', array(&amp;$this));<br />
$this-&gt;rewind_posts();<br />
return false;<br />
} elseif ($this-&gt;current_post + 1 &lt; $this-&gt;post_count) {<br />
return true;<br />
} elseif ($this-&gt;current_post + 1 == $this-&gt;post_count &amp;&amp; $this-&gt;post_count &gt; 0) {<br />
do_action_ref_array('loop_end', array(&amp;$this));<br />
$this-&gt;rewind_posts();<br />
}</code></p>
<p>Now we&#8217;ve solved problem 1, and 5 real posts are displaying on our front page, let&#8217;s move on to problem 2.</p>
<h3>Problem 2: previous page, or going to older posts will no longer work.</h3>
<p>Since pages are pretty obsolete at this point, <strong>we&#8217;ll switch to using offsets</strong>. This is because each page will no longer display a fixed number of posts, <strong>each may display a variable amount of posts, minimum being 5 (that we set just now), and maximum being 15 (that we set at the very beginning)</strong>. So to start we&#8217;ll hop over to our <code>index.php</code> in our theme file, and simply get the offset from the URL and pass it through to our post loop. Here goes:</p>
<p><code>&lt;?php if ($_GET['offset'] &amp;&amp; is_numeric($_GET['offset'])) {<br />
query_posts('offset='. $_GET['offset']); $offsetting = $_GET['offset'];<br />
} else { $offsetting = 0; } ?&gt;</code></p>
<p>So with that code in <code>index.php</code>, we can now visit <em>myblogsite.com/?offset=20</em> and offset our posts by 20. To determine how many posts to offset by in previous pages, we simply take how much we&#8217;re currently offset by, and add all the posts we&#8217;ve displayed on the page, regardless of whether or not it is an aside or a real post. To do this we need another counter. So we&#8217;ll initialise our counter, perhaps near the beginning of <code>index.php</code>:</p>
<p><code>&lt;?php $on_page = 0; ?&gt;</code></p>
<p>&#8230; then within our <code>while (have_posts()) {</code> loop, (or whatever equivalent loop your theme uses), we&#8217;ll just increment it:</p>
<p><code>&lt;?php $on_page++; ?&gt;</code></p>
<p>So then we recode our &#8220;previous posts&#8221; link to go to:</p>
<p><code>&lt;a href="http://yourblog.com/?offset=&lt;?php echo $offsetting + $on_page; ?&gt;" &gt;Previous posts&lt;/a&gt;</code></p>
<p>That was simple, eh? This brings us to problem 3.</p>
<h3>Problem 3: newer posts don&#8217;t work, for obvious reasons.</h3>
<p>Going forward in time is a little bit more complex. We want to calculate how much <em>less</em> we should offset by. To do this we&#8217;ll create a function to calculate this. The function will need to know how much we&#8217;re currently offset by. Based on that, <strong>it&#8217;ll query 15 posts into the future, then loop through those posts in reverse order</strong>. If it can&#8217;t go 15 posts into the future (eg: on the first page, and perhaps the second), it&#8217;ll go as far into the future as it can. <strong>When looping through, it&#8217;ll record the category of each of the posts</strong>. Whenever it hits a post, it&#8217;ll increment the count we want to offset less by. When we hit a post that category isn&#8217;t an aside (category 429 in my example), it&#8217;ll increment a counter that determines how many real posts we&#8217;ve hit so far. So therefore we have two counters. When the real counter hits 6 posts, it&#8217;ll terminate the offset counter. This is because I want 5 real posts per page, and based on how we coded problem 1, we know that the last post of any page must be a real post, not an aside.</p>
<p>We can place this function in the functions.php file of our theme. Here is the function, of which lazy people can copy and paste:</p>
<p><code>function back_to_the_future($offset = 0) {<br />
$new_offset = $offset-15;<br />
if ($new_offset &lt; 0) {<br />
$new_offset = 0;<br />
}<br />
$diff_offset = $offset - $new_offset;<br />
$future_query = new WP_Query(array(<br />
'showposts' =&gt; $diff_offset,<br />
'order' =&gt; 'DESC',<br />
'offset' =&gt; $new_offset,<br />
'do_not_terminate' =&gt; TRUE<br />
));</code></p>
<p><code>$post_data = array();</code></p>
<p><code>while ($future_query-&gt;have_posts()) {<br />
if ($diff_offset == 0) {<br />
break;<br />
} else {<br />
$diff_offset--;<br />
}<br />
$future_query-&gt;the_post();<br />
$cat_id = get_the_category();<br />
$cat_id = $cat_id[0]-&gt;cat_ID;<br />
$post_data[] = $cat_id;<br />
}</p>
<p>$post_data = array_reverse($post_data);<br />
$count_posts = 0;<br />
$count_total = 0;</p>
<p>foreach ($post_data as $post_cat) {<br />
if ($post_cat != 429) {<br />
$count_posts++;<br />
}<br />
if ($count_posts == 6) {<br />
break;<br />
} else {<br />
$count_total++;<br />
}<br />
}</p>
<p></code></p>
<p><code> return $offset - $count_total;<br />
}</code></p>
<p>People who looked through the code will realise that we passed the <code>do_not_terminate</code> variable to WP_Query that we set up when addressing Problem 1. This is required because if we didn&#8217;t, we won&#8217;t get 15 posts into the future, instead we&#8217;ll just get however many posts starting from 15 posts into the future that include 5 real posts &#8211; which is totally useless.</p>
<p>To finish off nicely we&#8217;ll edit our &#8220;newer posts&#8221; link to use this calculated offset in our <code>index.php</code> file, but only display when we have a proper offset to show and we&#8217;re not on the first page.</p>
<p><code>&lt;?php if ($future_offset != 0 || !empty($offsetting)) { ?&gt;<br />
&lt;a href="http://yourblog.com/?offset=&lt;?php echo $future_offset; ?&gt;"&gt;Newer Posts&lt;/a&gt;<br />
&lt;?php } ?&gt;</code></p>
<p>Tada &#8211; all done! I hope that helped somebody out there, but if not at least I have it for archival purposes. If you&#8217;re using it, let me know how it goes!</p>
<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://thinkmoult.com/2009/09/24/make-a-category-not-considered-as-a-post-in-wordpress/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>FrogCMS: a simple, clean CMS.</title>
		<link>http://thinkmoult.com/2009/09/22/frogcms-a-simple-clean-cms/</link>
		<comments>http://thinkmoult.com/2009/09/22/frogcms-a-simple-clean-cms/#comments</comments>
		<pubDate>Mon, 21 Sep 2009 17:28:50 +0000</pubDate>
		<dc:creator>Dion Moult</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[cms]]></category>
		<category><![CDATA[e2-productions]]></category>
		<category><![CDATA[frogcms]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://thinkmoult.com/?p=994</guid>
		<description><![CDATA[The other day I was looking for a CMS to run E2-Productions on. People who exclaim &#8220;what? You&#8217;re not going to engineer your own solution?&#8221; clearly have their priorities in the wrong places. If there&#8217;s one thing I learned in programming, it&#8217;s never, ever to reinvent the wheel. (unless you don&#8217;t know how wheels work [...]
No related posts.]]></description>
			<content:encoded><![CDATA[<p>The other day I was looking for a CMS to run E2-Productions on. People who exclaim &#8220;what? You&#8217;re not going to engineer your own solution?&#8221; clearly have their priorities in the wrong places. If there&#8217;s one thing I learned in programming, it&#8217;s <strong>never, ever to reinvent the wheel</strong>. (unless you don&#8217;t know how wheels work yet)</p>
<p>I wanted to make E2 easy to maintain, easy to update, and most of all easy to switch between different ideas of what the site should contain. A CMS was a clear solution to this problem. E2 is the site I plan to use to showcase my portfolio in greater detail. Wipup is free to host my works-in-progresses, and thinkMoult is and always should be just a blog.</p>
<p>Being such a simple site with mainly static pages (perhaps a contact form) it was clear that the big poisons like Joomla, Mambo, Drupal etc were clearly out of the picture. WordPress is a CMS but a pain when you look at the source, and is mainly targeted at blogs. Some poking around led me to discover <a href="http://www.madebyfrog.com/">FrogCMS</a>.</p>
<p>I downloaded the tarball, and had it up and running on my localhost within seconds. A quick tour around the administrator backend was enough to tell me this had all my needs covered. It supported markdown, templating, page hierarchies, and I think I glimpsed at some out-of-the-box SEO. Browsing their website also unearthed some useful plugins, although I think I will code for my needs manually.</p>
<p>The next step is to come up with a design. However, that&#8217;s not stopping me from using <a href="http://wipup.org">WIPUP</a> to start <a href="http://wipup.org/updates/view/6">tracking the upcoming upgrades on E2-Productions</a>!</p>
<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://thinkmoult.com/2009/09/22/frogcms-a-simple-clean-cms/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to use CodeIgniter&#8217;s OpenID library to integrate OpenID in your existing user system.</title>
		<link>http://thinkmoult.com/2009/02/22/use-codeigniter-openid-library-to-integrate-openid/</link>
		<comments>http://thinkmoult.com/2009/02/22/use-codeigniter-openid-library-to-integrate-openid/#comments</comments>
		<pubDate>Sun, 22 Feb 2009 08:42:19 +0000</pubDate>
		<dc:creator>Dion Moult</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[codeigniter]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[library]]></category>
		<category><![CDATA[login]]></category>
		<category><![CDATA[openid]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[register]]></category>

		<guid isPermaLink="false">http://thinkmoult.com/?p=478</guid>
		<description><![CDATA[Apparently OpenID is all the rage nowadays in the coding world and those using the CodeIgniter framework are left all alone without a proper guide on how to get it working. So as a budding programmer I is be halping all of you. Yes, it IS a long post, but it should help if you [...]
No related posts.]]></description>
			<content:encoded><![CDATA[<p>Apparently OpenID is all the rage nowadays in the coding world and those using the CodeIgniter framework are left all alone without a proper guide on how to get it working. So as a budding programmer I is be halping all of you. Yes, it IS a long post, but it should help if you read it step by step.</p>
<h4>INTRODUCTION</h4>
<p>Here is a nifty short guide to get people to use the CodeIgniter OpenID library to start using OpenID in your web application. Firstly I will assume you already have a registration system of some sort, and if you don&#8217;t, you should, because not everybody knows/cares about OpenID. What we have to do to spread OpenID is to provide a choice to people, not force them upon it &#8211; forcing people would simply get them to leave.</p>
<h4>BRIEFING OF SYSTEM</h4>
<p>So, let&#8217;s say you have a registration system that uses a table to store some sort of user ID (username/email/uid/whatever) and some sort of password. You also have a login form which all works fine, and now you want to allow people to use OpenID on that system.</p>
<p>Here&#8217;s the briefing on how it&#8217;s going to work. I&#8217;m assuming you know how OpenID is used already. I&#8217;m also assuming you are comfortable with PHP. What will happen is that in the place of the username field (or if you want you can make a separate form for it) people have the choice to just type in their OpenID URL, then ignore the password field. When they click the login button, firstly we will do a check for whether or not it is an OpenID URL.  If it is not valid, then we just continue checking if it&#8217;s a proper user account like our previous system and everything is fine. If it IS a valid OpenID URL, then it will perform the usual &#8220;please authenticate&#8221; checks with the OpenID server, and once that&#8217;s done, we&#8217;ll add an OpenID row to a NEW OpenID table which&#8217;ll store this stuff, and that table will also have a UID column, which allows us to bind an OpenID URL to a user account. <em>Note that this is a one way bind, so many OpenIDs can refer to a single user account, but not the other way around</em>.</p>
<p>This means<strong> you will have to create another table in your database</strong>, this depends on what type of database you are using, but in general you should have two columns:</p>
<p>Column 1) openid_url<br />
This would be a varchar field to store a canonicalised version of the openid<br />
url, for example http://foo.bar.com/</p>
<p>Column 2) user_id<br />
This would be an INT that would contain the userid of the username this openid<br />
url is binded to. This should be the key field as it must be unique.</p>
<p>Here is the SQL that should create this for you, but remember it only applies on SQL databases.</p>
<p><code>CREATE TABLE IF NOT EXISTS `user_openids` (<br />
`openid_url` varchar(255) NOT NULL,<br />
`user_id` int(11) NOT NULL,<br />
PRIMARY KEY  (`openid_url`),<br />
KEY `user_id` (`user_id`)<br />
) ENGINE=MyISAM DEFAULT CHARSET=utf8;</code></p>
<p>Now as a final note, what if a user already has account, but wants an OpenID to bind to that one instead of creating a new one? The simplest way to do this is to automatically create a new one, but have an option, perhaps in the user control panel or settings page that will allow them to &#8220;bind&#8221; to an existing account. They will have to provide that account&#8217;s user/pass to authenticate they are allowed to bind to it, and if they do, then the original account will be deleted, the user_id will change in the user_openids table, and the user will have to relogin to continue. Tada. Simple.</p>
<p>OK, let&#8217;s get started.</p>
<h4>STEP 1: Setting up the libraries.</h4>
<p>Alright, the first step is to get the library. You can <a href="http://codeigniter.com/wiki/OpenID/">obtain it from the CodeIgniter Wiki</a>.  Now go and <strong>upload all the files</strong>. This library is &#8230; well &#8230; just a CI library, so that means it&#8217;s limited to CI functions and so it also needs the actual PHP OpenID Library to actually interface with OpenID itself. So go and <a href="http://www.openidenabled.com/php-openid/">download the PHP OpenID Library</a> then <strong>upload the Auth/ directory in your system/application/libraries/ directory</strong>.  Note that this is the same place as the Openid.php file you uploaded from the CI OpenID Library. For those impatient folks who have already run the test controllers, it should&#8217;ve failed on you asking for mkdir permissions. Well, instead of chmodding our entire system, we&#8217;re just going to add those directories for it ourselves. <strong>Go to the CI root directory (the one that contains the system/ directory) and add another directory called tmp/. Go inside tmp/ and then add three more directories called associations/ and nonces/ and temp/</strong>. That should be enough to set up the library.</p>
<h4>STEP 2: Testing if it works.</h4>
<p>The next step, now that you supposedly have the files in the right places, is to check whether or not it works. Thankfully the CI OpenID library has already provided us with a test.php controller. So, what are you waiting for? <strong>Go to yoursite.com/test and put in your OpenID URL and see if it authenticates.</strong> Obviously if you don&#8217;t have an OpenID URL to test with, you need to go get one.  <a href="http://http://openid.net/get/">There are many providers available</a>. If it works flawlessly (don&#8217;t forget to test with a non-valid URL to see if it catches that too) then skip the next paragraph. Or you can read it anyway.</p>
<h4>OPTIONAL: If it doesn&#8217;t work?</h4>
<p>Now, let&#8217;s say it&#8217;s mucked up for you. If you get nonce already used errors, try clearing out all the files in the tmp/ directory you made earlier on. Other nonces errors or authentication/redirection errors can be a problem with your CI configuration. Go to your system/application/config directory and edit your config.php file. Look for the uri_protocol option and try all of the options there. I find AUTO works fine for me but on my remote server apparently it only likes ORIG_PATH_INFO. Another glitch I encountered on my localhost is that the server would deny my authentication request. This is probably an Apache setting on my localhost but I played so much with my Apache settings it&#8217;s probably all my fault. Uploading to my remote server showed it worked perfectly there, but if you&#8217;re having problems testing it on your localhost, you might want to apply this very dirty hack. Go to your system/application/libraries/Auth/ directory and edit the OpenID.php file. The very first function is called isFailure($thing). Now screw them but right now I don&#8217;t care about authentication because I know it works on a non-mucked up server. So comment out the return is_a($thing&#8230; line and add a line after then to just simply return false;. You&#8217;ll get:</p>
<p><code>function isFailure($thing)<br />
{<br />
<strong> //return is_a($thing, 'Auth_OpenID_FailureResponse');</strong><br />
<strong> return False;</strong><br />
}</code></p>
<p><strong>Note that I DO NOT RECOMMEND YOU DO THIS. IT IS A HACK IF YOU HAVE PROBLEMS RUNNING IT ON A TESTING SERVER. MAKE SURE YOU KNOW IT WORKS PROPERLY OTHERWISE.</strong></p>
<p>Ok. Assuming now everything is working fine on the test controller, let&#8217;s start integrating it into our system.</p>
<h4>STEP 3: Port the test controller to your own system.</h4>
<p>Now we having a working test controller, but it isn&#8217;t part of our own system yet. Let&#8217;s say you have another controller which contains a Users class which deals with people logging in. <strong>Comment out all the code so that after they try to login using your existing form, it does nothing</strong>. <em>Therefore, if your login form points to &lt;form action=&#8221;foo/bar&#8221;&gt;, you will comment out all the code in bar()</em>. Now we are going to add the OpenID check.</p>
<p>Because a test controller already exists, this speeds up the reverse engineering process significantly as we already have a working example of use. All we have to do is do code reuse in the right places. This is a bit hard to guide because all of our user systems are different in terms of the code. So here you&#8217;ll have to use your own wits on if you need modifications to work for your own system.</p>
<p>Here is the system flow chart of how things are going to work &#8211; existing processes you should already have on your system are marked in dotted lines:</p>
<p style="text-align: center;"><a href="http://thinkmoult.com/wp-content/uploads/2009/02/diagram1.png"><img class="size-full wp-image-479 aligncenter" title="diagram1" src="http://thinkmoult.com/wp-content/uploads/2009/02/diagram1.png" border="0" alt="diagram1" width="453" height="626" /></a></p>
<p>Firstly we want to look at section <strong>(A)</strong>. This section deals with checking if it is a valid OpenID URL. This can be done by copying the test controller function exactly. I have also added at the beginning some code, so read the comments as to why. Put this code in the function where your login form would normally point to in the &lt;form action=&#8221;foo/bar&#8221;&gt;. So therefore you would put it in the bar() function. <em>For the moment, we are going to disregard going to section </em><strong>(D)</strong><em>, as this is covered later on in </em><strong>Step 4</strong>. Here is the code you have to put in bar():</p>
<p><code> // Before we check if the username is in fact an OpenID, we must secure<br />
// the variable. OpenID refers to the url as $user_id, so be sure to assign<br />
// the value of the inputted openid to $user_id. Here is have used<br />
// $this-&gt;username but this might change on your system.<br />
$user_id = trim($this-&gt;username);<br />
$user_id = htmlspecialchars($user_id);</code></p>
<p><code>// Load the neccessary OpenID libraries as shown by the example.<br />
$this-&gt;lang-&gt;load('openid', 'english');<br />
$this-&gt;load-&gt;library('openid');</code></p>
<p><code>$this-&gt;config-&gt;load('openid');<br />
$req = $this-&gt;config-&gt;item('openid_required');<br />
$opt = $this-&gt;config-&gt;item('openid_optional');<br />
$policy = site_url($this-&gt;config-&gt;item('openid_policy'));<br />
$request_to = site_url($this-&gt;config-&gt;item('openid_request_to'));</code></p>
<p><code>$this-&gt;openid-&gt;set_request_to($request_to);<br />
$this-&gt;openid-&gt;set_trust_root(base_url());<br />
$this-&gt;openid-&gt;set_args(null);<br />
$this-&gt;openid-&gt;set_sreg(true, $req, $opt, $policy);<br />
$pape_policy_uris = array();<br />
$this-&gt;openid-&gt;set_pape(true, $pape_policy_uris);<br />
$this-&gt;openid-&gt;authenticate($user_id);</code></p>
<p>Now, to better integrate into your system (<em>this is optional, but HIGHLY recommended</em>) you should go into your system/application/config directory and edit the openid.php file. Edit it to fit your needs. openid_required is the required information you want to grab from the openid provider, and openid_optional is the optional information you want to grab. That&#8217;s all good and fine, but what we&#8217;re interested in is the <em>openid_request_to</em> variable. This is the link to the function that checks the authenticity of the openid URL.  Right now it goes to the test check function, but I would recreate this check() function in my own controller, as keeping it in a test controller is &#8230; stupid.</p>
<p>So if you change the <em>openid_request_to</em> option, <strong>you need to recreate the check() function</strong>. So it&#8217;s practically a copy and paste. Just copy the check() function from the test controller into the controller you want to store the check() function in. Here is the copy and pasted code, with some added comments to show where things happen:</p>
<p><code>/**<br />
* Checks for proper OpenID authentication.<br />
*/<br />
public function check()<br />
{<br />
$this-&gt;lang-&gt;load('openid', 'english');<br />
$this-&gt;load-&gt;library('openid');<br />
$this-&gt;config-&gt;load('openid');<br />
$request_to = site_url($this-&gt;config-&gt;item('openid_request_to'));</code></p>
<p><code>$this-&gt;openid-&gt;set_request_to($request_to);<br />
$response = $this-&gt;openid-&gt;getResponse();</code></p>
<p><code>switch ($response-&gt;status)<br />
{<br />
<strong> // This is probably the most important bit of the check. The switch case<br />
// statements. They're pretty obvious as to what they do. All the same,<br />
// I have bolded part of their names for the hard of thinking ... haha.</strong><br />
case Auth_OpenID_<strong>CANCEL</strong>:<br />
$data['msg'] = $this-&gt;lang-&gt;line('openid_cancel');<br />
break;<br />
case Auth_OpenID_<strong>FAILURE</strong>:<br />
$data['error'] = $this-&gt;_set_message('openid_failure', $response-&gt;message);<br />
break;<br />
case Auth_OpenID_<strong>SUCCESS</strong>:<br />
$openid = $response-&gt;getDisplayIdentifier();<br />
$esc_identity = htmlspecialchars($openid, ENT_QUOTES);</code></p>
<p><code>$data['success'] = $this-&gt;_set_message('openid_success', array($esc_identity, $esc_identity), array('%s','%t'));</code></p>
<p><code>if ($response-&gt;endpoint-&gt;canonicalID) {<br />
$data['success'] .= $this-&gt;_set_message('openid_canonical', $response-&gt;endpoint-&gt;canonicalID);<br />
}</code></p>
<p><code>$sreg_resp = Auth_OpenID_SRegResponse::fromSuccessResponse($response);<br />
$sreg = $sreg_resp-&gt;contents();</code></p>
<p><code>foreach ($sreg as $key =&gt; $value)<br />
{<br />
$$key = $value;<br />
$data['success'] .= $this-&gt;_set_message('openid_content', array($key, $value), array('%s','%t'));<br />
}</code></p>
<p><code>$pape_resp = Auth_OpenID_PAPE_Response::fromSuccessResponse($response);</code></p>
<p><code>if ($pape_resp)<br />
{<br />
if ($pape_resp-&gt;auth_policies)<br />
{<br />
$data['success'] .= $this-&gt;lang-&gt;line('openid_pape_policies_affected');</code></p>
<p><code>foreach ($pape_resp-&gt;auth_policies as $uri)<br />
{<br />
$data['success'] .= "&lt;li&gt;&lt;tt&gt;$uri&lt;/tt&gt;&lt;/li&gt;";<br />
}</code></p>
<p><code>$data['success'] .= "&lt;/ul&gt;";<br />
}<br />
else<br />
{<br />
$data['success'] .= $this-&gt;lang-&gt;line('openid_pape_not_affected');<br />
}</code></p>
<p><code>if ($pape_resp-&gt;auth_age)<br />
{<br />
$data['success'] .= $this-&gt;_set_message('openid_auth_age', $pape_resp-&gt;auth_age);<br />
}</code></p>
<p><code>if ($pape_resp-&gt;nist_auth_level)<br />
{<br />
$data['success'] .= $this-&gt;_set_message('openid_nist_level', $pape_resp-&gt;nist_auth_level);<br />
}<br />
}<br />
else<br />
{<br />
$data['success'] .= $this-&gt;lang-&gt;line('openid_pape_noresponse');<br />
}</code></p>
<p><code><strong> // At this point, we have authenticated the OpenID COMPLETELY, and<br />
// we have also grabbed whatever information we have requested. For<br />
// example:</strong></code></p>
<p><code><strong>// $nickname is the nickname we have grabbed in openid_required. It<br />
// may or may not be empty.<br />
echo $nickname;<br />
if ( !$nickname )<br />
{<br />
// If $nickname is blank, and we require it for our system, we<br />
// should now execute some code that will ask them to fill out a<br />
// nickname. This is for you to figure out. It will probably<br />
// loading a separate view or redirecting.<br />
}<br />
else<br />
{<br />
// If we have all the required information we need, we can move on<br />
// to section (C) in the flow chart.<br />
}</strong></code></p>
<p><code><strong> </strong><strong> // Remember we had to store the openid URL in a new table so we can<br />
// bind them to users? $esc_identity is the variable you need. Note:<br />
// it is canonicalised - that means that the format is standardized<br />
// such as foo.bar.com becomes http://foo.bar.com/.<br />
echo $esc_identity;</strong></code></p>
<p><code>break;<br />
}</code></p>
<p><code>$data['pape_policy_uris'] = array(<br />
PAPE_AUTH_MULTI_FACTOR_PHYSICAL,<br />
PAPE_AUTH_MULTI_FACTOR,<br />
PAPE_AUTH_PHISHING_RESISTANT<br />
);<br />
<strong> // I have commented out the load-&gt;view because we want to use our own<br />
// view. See flow chart. You will have to edit it so that it does what<br />
// YOU want it to do. All I am doing is showing you how to set up a<br />
// basic structure.</strong></code></p>
<p><code><strong> //$this-&gt;load-&gt;view('view_openid', $data); </strong><br />
}</code></p>
<p>Ok. After you&#8217;re sure you know or have a brief idea of what&#8217;s going on, also note that several other functions are referenced to. <strong>So you&#8217;ll also have to add the _set_message() function to this controller. Just copy and paste from the test.php controller. </strong>MAKE SURE YOU DO THIS.</p>
<p>Now we have a working check() function. So if we&#8217;re on the SUCCESS switch case statement, we now have the requested information we need and an open ID url. The requested information (in the example code above it&#8217;s $nickname) can be used in section <strong>(B)</strong> of the flow diagram, and the canonicalised openid URL can be used in section <strong>(C) </strong>of the flow diagram. So hooray! We now have a working OpenID system. How you are going to display the form to request for additional information is UP TO YOU on how you are going to add it, as it depends on your system.</p>
<h4>STEP 4: Integrate OpenID check with normal usersystem checks.</h4>
<p>We&#8217;re almost done here. Let&#8217;s take another look at section <strong>(A)</strong> of the flow diagram. Through reverse engineering the OpenID library, we can see that when it checks if it is a valid openid URL, and returns FALSE,<em> it will use the _set_message() function to and give an appropriate error message</em>. <strong>This _set_message() function can be found in the system/application/libraries/Openid.php file</strong>. If you look at it, it will echo the error message then call an exit(). Now, we don&#8217;t want to grudge our users with annoying error messages, especially if there is NOTHING wrong if they don&#8217;t provide an openid URL. (<em>Remember, I am assuming you are merging your existing login box with your openID login box. NOT making a new openid login box &#8211; if you are making a new login box, you can pretty much disregard this step</em>.) We also don&#8217;t want to call an exit(), because we want to continue with section <strong>(D)</strong>. So<strong> comment out the echo and the exit line</strong>. After commenting them out, we want to replace the exit with something that will tell our script to skip the rest of our OpenID check and go straight to our usual account checks.</p>
<p>Here&#8217;s how we do it. (There might be alternatives, but this is what I think is the easiest) <strong>We will add a header redirect in place of the exit; line</strong>. Here&#8217;s what you should get:</p>
<p><code>function _set_message($error, $msg, $val = '', $sub = '%s')<br />
{<br />
$CI =&amp; get_instance();<br />
$CI-&gt;lang-&gt;load('openid', 'english');<br />
<strong> //echo str_replace($sub, $val, $CI-&gt;lang-&gt;line($msg));</strong></code></p>
<p><code> </code></p>
<p><code> if ($error)<br />
{<br />
<strong> //exit;</strong><br />
<strong> header( 'Location: /foo/bar/0' ) ;</strong><br />
}<br />
}</code></p>
<p>Where foo/bar goes to the same place as your &lt;form action=&#8221;whatever&#8221;&gt; we talked about in the beginning. <em>Notice I pass a parameter &#8217;0&#8242; to the function</em>. <strong>This is so that we can restructure the existing bar() function to follow this sort of pseudo code</strong>:</p>
<p><code>function bar($check_openid=1)<br />
{<br />
if ( $check_openid )<br />
{<br />
// Here you execute the OpenID check code (NOT THE check() FUNCTION)<br />
// that you added in step 2.<br />
// Note that successful OpenID logins/registrations will occur in<br />
// the check() function, which is elsewhere.<br />
}</code></p>
<p><code> </code></p>
<p><code> if ( !$check_openid )<br />
{<br />
// Now you continue with the code the describes section (D) of the<br />
// flow diagram.<br />
}<br />
}</code></p>
<p>&#8230; and that&#8217;s it! You should now have the basis of a system that accepts both traditional user logins and OpenID. <strong>Obviously you have a lot of extra to add in but if you&#8217;re here anyway you should know how to adapt it to your system and what else you have to add</strong>. Particularly in sections <strong>(B)</strong> and <strong>(C)</strong>. I&#8217;m not going to guide you how to do those steps as it depends on what information you want, how you want to display your request form, and how your database is structured. I&#8217;m very sorry, but <strong>you will have to work it out yourself</strong>. (It shouldn&#8217;t be too hard)</p>
<p>I have tested this as this is a running documentation based on what I have done to integrate OpenID in my own CI run site. However of course there may be bugs and things I&#8217;ve missed out, any comments will be appreciated, and of course I will answer questions (just leave it as a comment)! :) Spelling corrections are also welcome.</p>
<p>Please do NOT copy this post. Just link to this page if you want to share it with others.</p>
<p>I hope it has helped! <strong>Please leave a comment as I love &#8220;thanks yous&#8221;.</strong></p>
<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://thinkmoult.com/2009/02/22/use-codeigniter-openid-library-to-integrate-openid/feed/</wfw:commentRss>
		<slash:comments>96</slash:comments>
		</item>
		<item>
		<title>How to Actually Use Your Computer: Part 3</title>
		<link>http://thinkmoult.com/2009/01/21/how-to-actually-use-your-computer-part-3/</link>
		<comments>http://thinkmoult.com/2009/01/21/how-to-actually-use-your-computer-part-3/#comments</comments>
		<pubDate>Wed, 21 Jan 2009 13:36:27 +0000</pubDate>
		<dc:creator>Dion Moult</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[ftp]]></category>
		<category><![CDATA[gtalk]]></category>
		<category><![CDATA[how to use your computer]]></category>
		<category><![CDATA[im]]></category>
		<category><![CDATA[irc]]></category>
		<category><![CDATA[jabber]]></category>
		<category><![CDATA[lamp]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[msn]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[part 3]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[rss]]></category>
		<category><![CDATA[skype]]></category>
		<category><![CDATA[ssh]]></category>
		<category><![CDATA[telnet]]></category>
		<category><![CDATA[xampp]]></category>

		<guid isPermaLink="false">http://thinkmoult.com/?p=402</guid>
		<description><![CDATA[Feeling in a rather procrastinatic (word?) nature, I&#8217;ve once again displayed my utter aptitude in presenting delayed articles. This is the third part in the series, so you might want to check out part 1 &#8211; a general overview on the types of computer users, and perhaps even part 2 &#8211; about web browsing, email [...]
No related posts.]]></description>
			<content:encoded><![CDATA[<p>Feeling in a rather procrastinatic (word?) nature, I&#8217;ve once again displayed my utter aptitude in presenting delayed articles. This is the third part in the series, so you might want to check out <a href="http://thinkmoult.com/2008/09/27/how-to-actually-use-your-computer-part-1/">part 1 &#8211; a general overview on the types of computer users</a>, and perhaps even <a href="http://thinkmoult.com/2008/10/25/how-to-actually-use-your-computer-part-2/">part 2 &#8211; about web browsing, email &amp; PIM, IMs, and document editing</a>.</p>
<p>Right now, being 00:18AM (and counting!) I&#8217;m going to continue this series to talk about a few hidden tricks and activities you could use your computer for that you might not be accustomed to normally.</p>
<h3>RSS Feeds</h3>
<p>It&#8217;s amazing how many people who don&#8217;t know what an RSS feed is. RSS stands for Really Simple Syndication (yeah, really) and is basically a format of a web feed. In technophobe terms, this means it&#8217;s a fancy new way you can access information. For example, you can access your emails through your email client, you can view web pages with your web browser, and now you can view RSS feeds with, well, an RSS aggregator (or reader). Ok, it&#8217;s more complex than that, but that&#8217;s all you really need to know.</p>
<p>Let&#8217;s use a practical example to explain the usefulness of an RSS feed. Let&#8217;s say you absolutely love the thinkMoult blog, and you want to keep up to date on it all the time without getting extra spam in your inbox notifying you of updates. Well, like most blogs, <a href="http://thinkmoult.com/?feed=rss2">we offer an RSS feed</a> (hint: that was a link to our feed URL) You can input that URL into your RSS aggregator (which is a program you can download), and you can now easily view each post just as it is: a snippet of information, instead of laid out in this bulky (though beautiful) webdesign. It allows you to quickly parse information from all around the web in bitesize pieces. Don&#8217;t read too many blogs? You can also use it perhaps for comics, such as Dilbert or XKCD. Now you don&#8217;t need to remind yourself to check those pages for updates every time you&#8217;re online.</p>
<h3>Multiple IM Protocols</h3>
<p>Now, that&#8217;s just a fancy and technical way of saying MSN Messenger isn&#8217;t the only thing that exists. You can use Skype! You can use Jabber (such as GTalk), Yahoo chat, and there are so many other popular IM services that people use, you might just need to sign in to those accounts to make sure you can contact all your clients or important whomevers you meet online. I personally use Skype, MSN, and GTalk all the time.</p>
<p>You might find it&#8217;s a hassle to manage the multiple accounts, but fear not! There are less handicapped programs than your Windows MSN Messenger that actually support multiple protocols! For example, I use Kopete on KDE, and I can sign into all my accounts (save for Skype) with just one client. It really makes life easier.</p>
<p>Also, I know it isn&#8217;t exactly IM, but you should also familiarise yourself with IRC. IRC stands for Internet Relay Chat, and it&#8217;s what the whole online community used before other things got invented. Right now it&#8217;s still a massively popular form of communication, though mostly populated by people of the more intelligent and technical sort. It&#8217;s basically a huge chatroom (think 800 people per channel) categorised by topic. There are many IRC servers, though the most common is arguably irc.freenode.net. What you&#8217;ll need is an IRC client (try HydraIRC on Windows or IRSSI on Linux), and connect to the irc.freenode.net server. Once in, you might want to try joining some channels related to what you&#8217;re interested in. For example, I can be found regularly in #gentoo, #gentoo-kde, #gentoo-chat, #blenderchat, #vim, and occasionally some others depending on what I&#8217;m doing.</p>
<h3>Set up a Personal Server</h3>
<p>Yes, you can easily set up your own web server, even on Windows. You don&#8217;t need to be a rocket scientist. There&#8217;s this nifty little prepackaged LAMP setup (that&#8217;s Linux Apache MySQL, and PHP) in the disguised form of XAMPP. The absense of the L means it probably works on Windows, eh? The extra P is probably for Python or Perl, but I haven&#8217;t poked too much in the package to find out personally.</p>
<p>What use is a personal server? You can dump your files in it, give others your IP, and then they can easily download files from you. If you&#8217;re on a network (even through your router), you can easily transfer files from one computer to another at speeds reaching up to 1gb per second (either that or the little notification window lied). If you&#8217;re into webdesign, or need an environment to run PHP scripts, that&#8217;s the perfect place to do it! Or even if you want to use PHPMyAdmin (oh, the extra P could be that too) to interface with your MySQL databases (if you use them, of course) a server is probably the most useful thing you could have.</p>
<h3>Set up some transfer protocols</h3>
<p>We&#8217;ve all known the popular protocols, FTP, SSH, SFTP, Telnet, etc. Why don&#8217;t you set it up on your own computer? Let people upload files to your computer. Let people connect to your computer and control it remotely! If you have an X server, let people do X tunneling through SSH so from anywhere you can access your GUI applications. Or if you&#8217;re braver, setup a VNC server too so that you can control it as though you were sitting right in front of it!</p>
<p>You&#8217;d probably have to do some research on how to set these up for your operating system (for Linux just check your package manager), but it&#8217;s worth it. The ability to remotely access and manipulate your data from anywhere in the world is priceless. It has plenty of uses too! You can access your files from anywhere (that&#8217;s the obvious one). You can debug applications or even your failing router. You can have two people connect to one computer and run tutorial sessions, or do Extreme Programming (a style which involves two programmers working at the same time).</p>
<p>A word of warning though, please learn how to secure these connections, you don&#8217;t want random people poking through your stuff.</p>
<p>Well, that&#8217;s it for this part of the series. I realise it&#8217;s turned ever so slightly more geeky, so I promise the next part will be a lot simpler. If you aren&#8217;t of the technologically savvy type and you are reading this, you have <em>a huge amount</em> of research to do before you can find out how to accomplish all these things. However, repeat after me: &#8220;<em>It&#8217;s worth it</em>.&#8221;</p>
<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://thinkmoult.com/2009/01/21/how-to-actually-use-your-computer-part-3/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>How to Make a Website Part 1 &#8211; The Environment</title>
		<link>http://thinkmoult.com/2009/01/12/how-to-make-a-website-part-1-the-environment/</link>
		<comments>http://thinkmoult.com/2009/01/12/how-to-make-a-website-part-1-the-environment/#comments</comments>
		<pubDate>Mon, 12 Jan 2009 09:46:24 +0000</pubDate>
		<dc:creator>Dion Moult</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[environment]]></category>
		<category><![CDATA[how to make a site]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[scripts]]></category>
		<category><![CDATA[site]]></category>
		<category><![CDATA[website]]></category>
		<category><![CDATA[website resources]]></category>

		<guid isPermaLink="false">http://thinkmoult.com/?p=338</guid>
		<description><![CDATA[Creating a new website from scratch into the next killer web-app is always tough, but the journey there can always be a fun one, given that your workflow is right, you know what you aim to achieve, and you&#8217;ve got the right tools for the job. I&#8217;ve decided to document the creation of The E2 [...]
No related posts.]]></description>
			<content:encoded><![CDATA[<p>Creating a new website from scratch into the next killer web-app is always tough, but the journey there can always be a fun one, given that your workflow is right, you know what you aim to achieve, and you&#8217;ve got the right tools for the job. I&#8217;ve decided to document the creation of The E2 Project, which is basically the re-creation of E2.</p>
<p><strong>During the documentation, I will also teach you the do&#8217;s and don&#8217;ts of website creation. These are often overlooked, and you&#8217;d definitely pick up a lot of tricks that normally take years of experience to develop.</strong></p>
<h3>Understanding the resources around you.</h3>
<p>Here&#8217;s a list of useful resources for the impatient: HTML, CSS, PHP, MySQL, Javascript, Ajax, Free scripts (yes, really), stock images, SVN, Git, Mercurial, Image editing applications (The GIMP), text editors (Vim).</p>
<p>OK, firstly I&#8217;m going to talk about setting up your mental and physical environment before you start a project. A lot of people who don&#8217;t develop with computer more than often disregard this <em>vital</em> step, and end up rushing or making a mess of things. The first step is to make sure you know what you want your site to do. Will it be a blog? Will it be your online portfolio? Will it be yet another youtube clone? If you know what it does, you should also know what type of person will use it, and what features it should have. You need to be clear on what features it should have, as that&#8217;s the bulk of any web-app.</p>
<p>Assuming that you now know what your site is about and what features it will offer, it&#8217;s time to make sure you really know what&#8217;s going on. Has it be done before? If it has, what can you offer that other sites don&#8217;t? What can you learn from existing websites? Are there useful javascript or ajax snippets that can give your webpage that extra zing that makes it stand out? For example, people developing a personal portfolio website might be interested in <a href="http://www.huddletogether.com/projects/lightbox/">Lightbox</a>, as that&#8217;ll improve continuity on the site and remove layout restrictions. It also makes things look cooler in general. (yes, I really said that)</p>
<p>The next step is to know your limits. You will need to know HTML back to front. Sure, you can forget tags, but as long as you know they exist, that&#8217;s fine. As the saying goes, <em>the great programmer doesn&#8217;t need to remember it all</em>. There&#8217;s really nothing wrong with using cheatsheets. If you do know HTML, make sure you know how to validate it. If you&#8217;re epically extreme about this, make sure you can get XHTML 1.0 Strict validation on all your pages. It&#8217;s all about discipline, and in the end it helps with cross-browser functionality and compatibility with newer devices like mobile phones. Just take the extra step, and please, oh please, validate your code.</p>
<p>Do you know CSS? Do you <em>use</em> CSS? Any site nowadays should only contain semantic markup and use CSS to effectively seperate design from layout. No matter what you do, <em>do not use tables for layouting</em>. It&#8217;s bad. It&#8217;s evil. It causes the folks in the #css IRC channel to condemn you to heck. It&#8217;s good practice. If you&#8217;re unsure what I&#8217;m talking about, <a href="http://www.hotdesign.com/seybold/index.html">read this handy guide</a>. Of course, also don&#8217;t forget to validate your CSS code.</p>
<p>Do you know PHP and MySQL? True, this isn&#8217;t <em>the</em> only way to make sites, but it sure is popular, and hell powerful. How good are you at it? Do you know OOP, do you know MVC (or other framework styles)? If you answered no to either one, take your time to go and re-learn PHP. <a href="http://thinkmoult.com/2008/12/20/codeigniter-simple-clean-mvc-framework-for-php/">You&#8217;ll might find you&#8217;ve been doing it all wrong</a>. Don&#8217;t disregard that warning, really, take your time and re-learn what it is.</p>
<p>How big is the project? Do you need version control for it? It&#8217;s quite comon for people to dump version control for web projects, even individual ones, as it really makes the developing stage less confusing. If you don&#8217;t know what version control is, try search it up, then search up CVS, SVN, git, and Mercurial. You should try it out on your system, get familiar with it and perhaps use it in your next project.</p>
<p>Are you good at design? This does not necessarily mean you have to be a wiz at something like Photoshop (ewww) or The GIMP, there are some really simple designs that look amazing. If you do follow the &#8220;Create graphic image&#8221; -&gt; &#8220;Slice&#8221; -&gt; &#8220;Create web-app&#8221; workflow like most do, do you know how to use CSS in the slicing stage? Do you know how to create a design that won&#8217;t break in flexible layouts? Do you know how to solve the never-ending battles with CSS and IE? (Yes, all those dirty coding hacks that are so troublesome)? Do you have good stock graphics? Most disregard stock graphics, but they really add shine to the page. Have you considered web load-times and optimisation when designing? There are hundreds of things to consider, and over time all these things become natural.</p>
<h3>Don&#8217;t underestimate planning and protoypes.</h3>
<p>Don&#8217;t underestimate the importance of this step either due to the shortness of this section. User Interface is almost <strong>the most important thing that exists on a webpage</strong>. Don&#8217;t get me wrong, I&#8217;m not saying that your backends and server-side scripts aren&#8217;t going to do the trick too, it&#8217;s just that your site is going to be <em>used</em>. To be honest, change the splash image of any application, and even if you don&#8217;t add any new features, it already looks as though it&#8217;s had a bunch of action packed updates over the last version. You want to have a clear idea of several things:</p>
<ol>
<li><strong>The homepage of the site.</strong> This is the very first page people see, and the most important of all. This is what gives them their first impression, this is the page that should explain <em>what you do, why you exist, and how you can benefit the user</em> in less than a minute. This will be the central template design (especially for large scale sites) that defines the organisational structure and navigation style used throughout. Do not <em>ever</em> be inconsistent with design.</li>
<li><strong>Your databases.</strong> Yes, that&#8217;s right. You want to know what&#8217;ll be stored, where it&#8217;ll be stored, what&#8217;s the best way to store it so it can be used efficiently. The word that must be drilled into your head is <strong>modularisation</strong>. (Not a real word, but we aren&#8217;t learning English here, are we?) Basically, you want to use it one way, and any way you might think of in the future. I&#8217;ll cover this in more detail when I talk about setting up databases later.</li>
<li><strong>The system and framework.</strong> Yes, I stress frameworks again. Too many a PHP script kiddy has spewed out nothing but spaghettic logic. It&#8217;s not a fate you deserve. What framework are you going to use? Build your own? Use a preexisting one? Any needed libraries? How should you divide the logic framework into modules?</li>
</ol>
<h3>Work, flow. Work!</h3>
<p>The third and last topic I will cover in Part 1 of this series is workflow. This is VITAL. Read that again. That&#8217;s the acronym for Very Important Topic Aids Learning. I won&#8217;t go into much detail, because all my next parts will focus on workflow too. Some thing you might have noticed here. I did not mention servers or domains. That is NOT your concern. Too much worrying about servers and domains will leave you with a crappy system that&#8217;s up 100% of the time. Which nobody wants. You need to make your site? Need a server? <strong>Install Apache on your localhost and build it there.</strong> Don&#8217;t waste money on a half-baked-idea.com.</p>
<p>Workflow is amazingly flexible, but there are some one-size-fits-all that works. The first thing you want to get out of your way is the environment stuff I talked about in the first topic I covered. Know back to front what&#8217;s going on and how it&#8217;s going to go on. Assuming you have that all worked out, you&#8217;d want to create a design using an image editing program. Even if your site is something like Google or Yahoo that has a high text:image ratio, you want to visualise it first. No point playing around with CSS if you haven&#8217;t got a clear image in your head. Once you&#8217;ve got your visualisation done (good for the home page), create a valid HTML and CSS slice of the page. Split it up into template files and start organising and creating dummy filesystem structures in your framework. Create a couple static non-dynamic pages just to check the flexibility of the layout (stretches, different tags: forms, inputs, divs, headers), check cross-browser compatibility, and then when you&#8217;re done, make the home page and fill it with placeholders as necessary.</p>
<p>Now you can start working on the actual logic and system of the website (excluding previous framework setup). The first step is to create all your needed database tables, and choose the appropriate field types and set values. After this, since I use an MVC framework for most of my sites, I like to work pretty much &#8230; <em>in that order</em>. I build the models first, build the views, then just connect everything beautifully with the controllers. I generally like to start with building the user system, which is often the key and wire system of a website. This covers easy stuff like database input, form building, error and message templates, and general usability of the site. It&#8217;s the perfect &#8220;mini-system&#8221; to test the effectiveness of your framework, templating system, and helper libraries.</p>
<p>It all pretty much spins off from there, before venturing to code debugging, stress and user testing, hacking preventation, and advertising. Website creation is a huge topic, and unfortunately a text-heavy one too. Hopefully I&#8217;ll write part 2 soon!</p>
<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://thinkmoult.com/2009/01/12/how-to-make-a-website-part-1-the-environment/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>CodeIgniter &#8211; Simple, clean, MVC framework for PHP.</title>
		<link>http://thinkmoult.com/2008/12/20/codeigniter-simple-clean-mvc-framework-for-php/</link>
		<comments>http://thinkmoult.com/2008/12/20/codeigniter-simple-clean-mvc-framework-for-php/#comments</comments>
		<pubDate>Sat, 20 Dec 2008 12:29:21 +0000</pubDate>
		<dc:creator>Dion Moult</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[codeigniter]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[mvc]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://thinkmoult.com/?p=306</guid>
		<description><![CDATA[People learning PHP go through the wonderful stages of &#60;?php echo 'Hello, world!'; ?&#62;, the then branch off into either: 1) Wow! It&#8217;s so dynamic! Let&#8217;s create everything right here right now! or 2) Wow! It&#8217;s so messed up I don&#8217;t know $int from $char! Unfortunately, the people who belong in (1) tend to spend [...]
No related posts.]]></description>
			<content:encoded><![CDATA[<p>People learning PHP go through the wonderful stages of <code>&lt;?php echo 'Hello, world!'; ?&gt;</code>, the then branch off into either: 1) Wow! It&#8217;s so dynamic! Let&#8217;s create everything right here right now! or 2) Wow! It&#8217;s so messed up I don&#8217;t know <code>$int</code> from <code>$char</code>! Unfortunately, the people who belong in (1) tend to spend the next couple years in an ignorant bliss, spewing out hundreds of lines of non-OOP code with a structure somewhat like this:</p>
<blockquote>
<pre><code>&lt;?php
include './inc/template/header.php';
if ( $p == '' )
{</code></pre>
<pre style="padding-left: 30px;">include './inc/pages/index.php';</pre>
<pre><code>}
elseif ( $p == 'about')
{</code></pre>
<pre style="padding-left: 30px;">include './inc/pages/about.php';</pre>
<pre><code>}</code></pre>
<pre><strong>[... etc ...]</strong></pre>
<pre><code>else
{</code></pre>
<pre style="padding-left: 30px;">include './inc/template/404.php';</pre>
<pre><code>}
include 'footer.php';
?&gt;</code></pre>
</blockquote>
<p>Well. Look familiar to anybody? (or <em>even worse</em> examples!) Hah! My good sir, you have just missed out on the programming epiphany of the century. Any script kiddy with the guts to program before learning OOP should have their guts removed, quartered, and stuck up as a warning to other coders. So, if you are doing PHP, but you don&#8217;t know what OOP or MVC is &#8211; here is your cue to fricassé your arse and get ready for some late nights of programming ecstasy.</p>
<p>This post is somewhat a half-rant about the disadvantages of coding without any OOP or proper framework, and also a sort of happy unrelated babble talk brought about by me recently opening up (g)Vim again to code some very simple PHP, then taking a look at <em>POSE2</em>. For those that don&#8217;t know, <em>POSE2</em> was the project to basically make E2 as open as possible. It&#8217;s an MVC (Model-View-Controller) framework, with no built-in helper classes. It&#8217;s extremely minimalistic. It was used to construct VisionBin, and <a href="#mce_temp_url#">E2-Productions.com</a> currently runs on it too.</p>
<p>Hilariously enough, I fell into the common programmer trap of recreating the wheel. That&#8217;s why now, instead of advertising my oh-so-awesome <em>POSE2</em> system, I&#8217;m going to be recommending you CodeIgniter. CI is a fast, clean, <em>superbly </em>documented MVC PHP framework. Or so I say before trying it out properly. Let&#8217;s actually see how awesome it is. I will type this post out <em>live</em> as I convert the extremely simple E2 site from <em>POSE2</em> to CI.</p>
<p>Ok, apparently my connection hates me as it keeps on failing to download the tiny CI source files. After several retries, I finally am ready to start &#8230;. ok, uploading onto E2. This is great as I don&#8217;t get a lot of extra unneeded files in the / directory (except for index.php, obviously!), so everything is nicely tucked away in the system directory. Ok, quite a lot of files being uploaded here, but compared to other frameworks, this is slim. Let&#8217;s try visiting it without bothering to read any installation documents. Yep, already, it&#8217;s working without any needed config. I don&#8217;t see any installation docs (perhaps I&#8217;m just blur) but I do notice a config/ directory. It&#8217;s wonderfully documented and there&#8217;s quite a minimal amount to setup. .htaccess is a pain to setup due to specific server configurations (took quite a bit of debugging, but the option to fix it was hidden in the configuration), but other than that, it worked flawlessly. Easy to create new views, models, and controllers. Lots of helper classes &#8211; perfect, looks like exactly what anybody needs. Embeddable views to enable for templating&#8230;perfect.</p>
<p>First impression: wonderful, fast, user-friendly and amazingly well documented. Will give future updates on how I find it as I use it more. Meanwhile, I definitely recommend it to people.</p>
<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://thinkmoult.com/2008/12/20/codeigniter-simple-clean-mvc-framework-for-php/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Learn how to make a basic website framework.</title>
		<link>http://thinkmoult.com/2008/03/23/learn-how-to-make-a-basic-website-framework/</link>
		<comments>http://thinkmoult.com/2008/03/23/learn-how-to-make-a-basic-website-framework/#comments</comments>
		<pubDate>Sun, 23 Mar 2008 05:30:00 +0000</pubDate>
		<dc:creator>Dion Moult</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[website]]></category>

		<guid isPermaLink="false">http://thinkmoult.com/?p=13</guid>
		<description><![CDATA[This will teach you how to setup one page for all pages! So it&#8217;ll be a lot easier when changing layouts! Not only that, say GOODBYE to /index.php?page=contact&#8230;now you can just have /contact without actually making the directory! This will ALSO teach you how to have a site which you can easily switch version (like [...]
No related posts.]]></description>
			<content:encoded><![CDATA[<p>This will teach you how to setup one page for all pages! So it&#8217;ll be a lot easier when changing layouts!<br />
Not only that, say GOODBYE to /index.php?page=contact&#8230;now you can just have /contact without actually making the directory!<br />
This will ALSO teach you how to have a site which you can easily switch version (like when running parallel systems) when you are working on a new version and you don&#8217;t want others to know. It will have password protection which will allow only authorized users to test the version.<br />
Say goodbye to &#8220;coming soon&#8221; pages!</p>
<p>Ok, first we want a layout&#8230;Let&#8217;s be simple (just forget validation temporarily, this just an example):</p>
<p>My title.&lt;br /&gt;<br />
&lt;a href=&#8221;http://site.com&#8221;&gt;Home&lt;/a&gt;&lt;br /&gt;<br />
&lt;a href=&#8221;http://site.com/asdf&#8221;&gt;asdf&lt;/a&gt;&lt;br /&gt;<br />
content will go here&lt;br /&gt;<br />
Copyright.</p>
<p>Let&#8217;s save that file as index.php. Save it in a directory called &#8220;versionname&#8221; (you can change this, but remember to change the rest of the code as well) Now, replace &#8220;content will go here&#8221; with this:</p>
<p>&lt;?php<br />
if($page == &#8220;&#8221;) {<br />
include &#8220;/home/username/public_html/versionname/home.php&#8221;;<br />
} elseif($page == &#8220;asdf&#8221;) {<br />
include &#8220;/home/username/public_html/versionname/asdf.php&#8221;;<br />
} else {<br />
echo &#8220;error&#8221;;<br />
}<br />
?&gt;</p>
<p>Basically, it will see what the value of the variable $page is and accordingly, it will display the correct page.<br />
Create a new page called home.php (you can put whatever you want in it), and save it in the &#8220;versionname&#8221; directory. Then create a new page called asdf.php and put whatever you want in it and save it in the &#8220;versionname&#8221; directory.</p>
<p>Now try and go to yoursite.com/versionname. It will display your home page. Then go to yoursite.com/versionname/?page=asdf. It will display your asdf page. Let&#8217;s say in the future you decide to change your layout&#8230;you only need to change one page&#8230;the index.php page.</p>
<p>Ok. now instead of ?page=asdf, lets turn it into just /asdf. Go into your public_html folder (or your equivalent of it) and search for .htaccess. Open it up. This is apache server scripting. Won&#8217;t go into much detail though. You&#8217;re probably annoyed because you want your homepage to be in yoursite.com and not yoursite.com/versionname. Simple, add this code in .htaccess:</p>
<p>RewriteEngine on<br />
RewriteBase /</p>
<p>ReWriteRule ^/$ versionname/index.php<br />
ReWriteRule ^$ versionname/index.php</p>
<p>Now, try to go to yoursite.com. Amazing! The URL didn&#8217;t even change! Now to change into /asdf. add this:</p>
<p>ReWriteRule ^asdf/$ versionname/index.php?page=asdf<br />
ReWriteRule ^asdf$ versionname/index.php?page=asdf</p>
<p>Now, go to yoursite.com/asdf. Amazing! It showed the ?page=asdf page!<br />
Ok, now that you&#8217;ve done all that, let&#8217;s say you want a new version, but you don&#8217;t want to delete everything and setup a coming soon page. Create your new version in a directory called &#8220;versionname2&#8243;.<br />
Now, you want people to be able to access your new version, but not all people. So here&#8217;s what you do. Add this to the top of your versionname (not 2) index.php:</p>
<p>&lt;?php<br />
session_start();<br />
header(&#8220;Cache-control: private&#8221;);<br />
if( $_POST[beta] ) {<br />
if( $_POST[pass] == &#8220;yourpassword&#8221; ) {<br />
$_SESSION["beta"] = &#8220;1&#8243;;<br />
}}<br />
if( $_SESSION[beta] == 1 ) {<br />
include &#8220;/home/username/public_html/versionname2/index.php&#8221;;<br />
} else {<br />
?&gt;</p>
<p>And now, add the form below to wherever you want the verification to be:</p>
<p>&lt;form method=&#8221;post&#8221; action=&#8221;"&gt;&lt;br /&gt;<br />
&lt;input name=&#8221;pass&#8221; type=&#8221;password&#8221; class=&#8221;input&#8221;&gt;<br />
&lt;input name=&#8221;beta&#8221; type=&#8221;submit&#8221; value=&#8221;betatest&#8221;&gt;<br />
&lt;/form&gt;</p>
<p>So now, when you type in the password &#8220;yourpassword&#8221; in the form, you will be browsing your new version, with no edited URLs! Of course, to make it fully compatible you need to add the if $page=&#8221;" statements to your versionname2 index.php, but that&#8217;s simple to do.<br />
Ok, you&#8217;ve finished coding your new version. Simple, just go to your .htaccess, and replace all the /versionname to /versionname2. Done! You&#8217;ve succesfully upgraded your site.</p>
<p>Note: this is very basic but I hope it has helped some of you.</p>
<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://thinkmoult.com/2008/03/23/learn-how-to-make-a-basic-website-framework/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

