<?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>WGO</title>
	<atom:link href="http://www.wiseguysonly.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.wiseguysonly.com</link>
	<description>Tim Roberts CakePHP, MySQL and jQuery Developer</description>
	<lastBuildDate>Thu, 02 Feb 2012 19:22:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>CakePHP 2 &#8211; Hashing passwords before saving.</title>
		<link>http://www.wiseguysonly.com/2012/02/02/cakephp-2-hashing-passwords-before-saving/</link>
		<comments>http://www.wiseguysonly.com/2012/02/02/cakephp-2-hashing-passwords-before-saving/#comments</comments>
		<pubDate>Thu, 02 Feb 2012 17:41:59 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[Personal]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.wiseguysonly.com/?p=510</guid>
		<description><![CDATA[A quick gotcha here that leverages CakePHP&#8217;s inbuilt utilities to hash data before you commit it to the database. The beauty of this method is that you can still run all your validation checks and then hash the data between validation and saving. Why is that important? Consider you have a rule that says a [...]]]></description>
			<content:encoded><![CDATA[<p>A quick gotcha here that leverages CakePHP&#8217;s inbuilt utilities to hash data before you commit it to the database.</p>
<p>The beauty of this method is that you can still run all your validation checks and then hash the data between validation and saving. Why is that important? Consider you have a rule that says a password should be no more than 15 characters. When you hash it, it would break the rule and your record would never save. </p>
<p>All you have to do is hash your fields in the beforeSave function of your model like this example from a User Model:</p>
<p><code><br />
        public function beforeSave() {<br />
                App::uses('Utitlity','Security');<br />
                if(!empty($this->data['User']['password'])) {<br />
                        $this->data['User']['password'] = Security::hash($this->data['User']['password']);<br />
                }<br />
                return true;<br />
        }<br />
</code></p>
<p>One import aspect of this is to always return true. If you don&#8217;t your record will NEVER save.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.wiseguysonly.com/2012/02/02/cakephp-2-hashing-passwords-before-saving/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Installing mongoDB on Debian Squeeze (and Ubuntu).</title>
		<link>http://www.wiseguysonly.com/2011/09/04/installing-mongodb-on-debian-squeeze-and-ubuntu/</link>
		<comments>http://www.wiseguysonly.com/2011/09/04/installing-mongodb-on-debian-squeeze-and-ubuntu/#comments</comments>
		<pubDate>Sun, 04 Sep 2011 18:07:22 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Personal]]></category>

		<guid isPermaLink="false">http://www.wiseguysonly.com/?p=506</guid>
		<description><![CDATA[There&#8217;s no point in me trying to sell mongoDB to you, just go over to the mongoDB site and read up on its excellence. This is how I got mongoDB working on Debian Squeeze. It should work for other Deb based flavours &#8211; I&#8217;m thinking Ubuntu. I also have a PHP5x setup so you may [...]]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s no point in me trying to sell mongoDB to you, just go over to <a href="http://www.mongodb.org/">the mongoDB site</a> and read up on its excellence. </p>
<p>This is how I got mongoDB working on Debian Squeeze. It should work for other Deb based flavours &#8211; I&#8217;m thinking Ubuntu. I also have a PHP5x setup so you may need to adapt if you are running earlier versions. I&#8217;m also assuming you have git installed to fetch the drivers.</p>
<p><strong>All you have to do follows:</strong></p>
<p>First install the necessary mongo stuff (you need php5-dev also as we need the phpize functionality):</p>
<p><code>sudo apt-get install mongodb mongo-clients php5-dev</code></p>
<p>Now fetch the official mongoDB php driver from github:</p>
<p><code>git clone https://github.com/mongodb/mongo-php-driver.git</code></p>
<p>Change into the driver directory and run the following commands:</p>
<p><code>cd mongo-php-driver<br />
phpize<br />
./configure<br />
sudo make install</code></p>
<p>Copy the driver to php extension dir. To find your extension dir run:</p>
<p><code>php -i | grep  extension_dir</code></p>
<p>Armed with the location of your extension dir copy the file:</p>
<p><code>sudo cp modules/mongo.so  /path/to/php/extension_dir/ </code></p>
<p>Now create a file to load the driver into php at start up:</p>
<p><code>sudo vi /etc/php5/conf.d/mongo.ini</code></p>
<p>with the line:</p>
<p><code>extension=mongo.so</code></p>
<p>Now restart apache:</p>
<p><code>sudo /etc/init.d/apache2 restart</code></p>
<p>Then start an instance of the mongo server and PHP should be mongo friendly.</p>
<p>If you want to test this go grab a copy of the excellent <a href="http://www.phpmoadmin.com/">phpMoAdmin</a> and drop the file anywhere you load it through a browser. It should connect off the bat to mongoDB and you can start creating collections and objects in less time than it takes you to type &#8220;CREATE TABLE &#8230;&#8221;.</p>
<p>Enjoy.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.wiseguysonly.com/2011/09/04/installing-mongodb-on-debian-squeeze-and-ubuntu/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Behaviour Driven Development for web developers and their clients.</title>
		<link>http://www.wiseguysonly.com/2011/08/28/behaviour-driven-development-for-web-developers-and-their-clients/</link>
		<comments>http://www.wiseguysonly.com/2011/08/28/behaviour-driven-development-for-web-developers-and-their-clients/#comments</comments>
		<pubDate>Sun, 28 Aug 2011 19:53:38 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Personal]]></category>

		<guid isPermaLink="false">http://www.wiseguysonly.com/?p=500</guid>
		<description><![CDATA[It sells itself: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 Feature: Tutor [...]]]></description>
			<content:encoded><![CDATA[<p>It sells itself:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
</pre></td><td class="code"><pre class="gherkin" style="font-family:monospace;">Feature: Tutor forums
	As a Tutor
	I want to be able to use the forums
	In order to communicate with other tutors
&nbsp;
Scenario: View forums
	Given that I am logged in as a Tutor
	And I click on &quot;Tutor Forums&quot;
	Then I should see a paginated list of &quot;Tutor Forums&quot;
&nbsp;
Scenario: Create forum
	Given that I am logged in as a Tutor
	And I am on the page &quot;Tutor Forums&quot;
	And I click on the link Create forum
	And I enter a Forum title
	And I click &quot;create forum&quot;
	Then I should be able to create a new forum.
&nbsp;
Scenario: Edit forum
	Given that I am logged in as a Tutor
	And I am viewing a forum that I created
	And The forum was created within the past 15 minutes
	Then I should be able to edit the forum
&nbsp;
Scenario: View threads
	Given that I am logged in as a Tutor
	And I am on the page &quot;Tutor Forums&quot;
	And I click on the title of a Forum
	I should see a paginated list of threads for that forum.
&nbsp;
Scenario: Read thread
	Given that I am logged in as a Tutor
	And I am viewing a list of forum threads
	And I click the title of a thread
	Then I should see a list of message for that thread.
&nbsp;
Scenario: Reply to thread
	Given that I am logged in as a Tutor
	And I am viewing a thread
	And I click &quot;post reply&quot;
	And I enter a reply
	And I click &quot;post reply&quot; button
	Then I should be abÃ±le to reply to a thread
&nbsp;
Scenario: Edit reply
	Given that I am logged in as a Tutor
	And I am viewing replies to a thread
	And a reply was posted by me
	And the reply was posted within the last 15 minutes
	Then I should be able to edit the reply.</pre></td></tr></table></div>

<p>It&#8217;s so easy you and your clients can learn it in minutes, and it saves everyone time and clarifies expectations.</p>
<p>PHP users should check out <a href="http://behat.org/">Behat</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.wiseguysonly.com/2011/08/28/behaviour-driven-development-for-web-developers-and-their-clients/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CakePHP Development</title>
		<link>http://www.wiseguysonly.com/2011/07/09/cakephp-development/</link>
		<comments>http://www.wiseguysonly.com/2011/07/09/cakephp-development/#comments</comments>
		<pubDate>Sat, 09 Jul 2011 11:34:40 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Agile Programming]]></category>
		<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.wiseguysonly.com/?p=473</guid>
		<description><![CDATA[The new website for my CakePHP development company, Zumo Internet is now live. I&#8217;ve been building with PHP for 10 years, but over the past 2 years all of my projects have been built using CakePHP. I&#8217;ve never looked back as far as stability and speed of development is concerned. So if you are looking [...]]]></description>
			<content:encoded><![CDATA[<p>The new website for my <a title="CakePHP development" href="http://www.zumointernet.com">CakePHP development</a> company, Zumo Internet is now live.</p>
<p>I&#8217;ve been building with PHP for 10 years, but over the past 2 years all of my projects have been built using CakePHP. I&#8217;ve never looked back as far as stability and speed of development is concerned.</p>
<p>So if you are looking for a CakePHP developer, please visit and maybe hire me.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.wiseguysonly.com/2011/07/09/cakephp-development/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using CakePHP without a database</title>
		<link>http://www.wiseguysonly.com/2011/06/17/using-cakephp-without-a-database/</link>
		<comments>http://www.wiseguysonly.com/2011/06/17/using-cakephp-without-a-database/#comments</comments>
		<pubDate>Fri, 17 Jun 2011 10:33:04 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[prototyping]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.wiseguysonly.com/?p=434</guid>
		<description><![CDATA[I enjoy CakePHP&#8217;s structure and methods so much that I have started  using it for my non-database driven projects and for prototyping big projects. However, when no database is present CakePHP throws a warning that it can&#8217;t connect to the database. The solution is to create a dummy database connection to convince CakePHP that all [...]]]></description>
			<content:encoded><![CDATA[<p>I enjoy CakePHP&#8217;s structure and methods so much that I have started  using it for my non-database driven projects and for prototyping big projects.</p>
<p>However, when no database is present CakePHP throws a warning that it can&#8217;t connect to the database. The solution is to create a dummy database connection to convince CakePHP that all is ok. And, it&#8217;s as simple as this:</p>
<p>Create a new folder <code>app/models/datasources/dbo</code></p>
<p>Create a new file at <code>app/models/datasources/dbo/dbo_dummy_db.php</code> and add the following:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>   
    <span style="color: #000000; font-weight: bold;">class</span> DboDummyDb <span style="color: #000000; font-weight: bold;">extends</span> DboSource <span style="color: #009900;">&#123;</span>         
                 <span style="color: #000000; font-weight: bold;">function</span> connect<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>  <span style="color: #009900;">&#123;</span>                
                          <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">connected</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span>
                          <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">connected</span><span style="color: #339933;">;</span>
                  <span style="color: #009900;">&#125;</span>
            <span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>In your app/config/database.php find the default connection array &#8211; a line that starts <code>$default = array</code><br />
and replace the line for the driver from<br />
<code>'driver' =&gt; 'mysql'</code>,<br />
to<br />
<code>'driver' =&gt; 'dummy_db',</code></li>
<p>And that&#8217;s all there is to using CakePHP without a database.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.wiseguysonly.com/2011/06/17/using-cakephp-without-a-database/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Removing tracked files from git without deleting them</title>
		<link>http://www.wiseguysonly.com/2011/06/13/removing-tracked-files-from-git-without-deleting-them/</link>
		<comments>http://www.wiseguysonly.com/2011/06/13/removing-tracked-files-from-git-without-deleting-them/#comments</comments>
		<pubDate>Mon, 13 Jun 2011 09:01:50 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Agile Programming]]></category>
		<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[Personal]]></category>
		<category><![CDATA[SCM]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.wiseguysonly.com/?p=426</guid>
		<description><![CDATA[&#8212; DISCLAIMER: someone may tell me where I went wrong shortly after publication &#8212; When I develop CakePHP apps, my local database configiration file is very different from the live one. Therefore, when I am using Git to push my changes to a live environment I want to be sure this file is not pushed. [...]]]></description>
			<content:encoded><![CDATA[<p><em>&#8212; DISCLAIMER: someone may tell me where I went wrong shortly after publication &#8212;</em></p>
<p>When I develop CakePHP apps, my local database configiration file is very different from the live one. Therefore, when I am using Git to push my changes to a live environment I want to be sure this file is not pushed. Fortunately Git  has the ability to let me do this with the .gitignore file. I can specify the following:</p>
<p><code>app/config/database.php</code></p>
<p>One path to file on each line will ignore those files.</p>
<p>However, I recently found myself in the situation where I had already added files I wanted to ignore to my repository. After reading the docs and several forums, the answer seemed to be using the following command:</p>
<p><code>git rm --cached filename</code></p>
<p>I did this, commited my changes, then pushed them live. Horror. The database.php had been removed on my local repo and this was subsequently pushed to the live site which duly collapsed. Fortunately I used Git to quickly revert my changes. I&#8217;ve no idea why the command above didn&#8217;t work for me, but I did find a failsafe way of removing a tracked file without deleting it.</p>
<ol>
<li>make sure the path to file is listed in your .gitignore</li>
<li>copy the file outside of your repo.</li>
<li>do a <code>git rm -rf path/to/file.ext</code></li>
<li>do a git commit to remove the file from the repo</li>
<li>copy the file back from where you placed it in step 2</li>
</ol>
<p>You should be able to change the file now and when running git status it should not show up.</p>
<p>It may seem long winded and a more-than-likely unorthodox to do it this way, but it makes me feel safer.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.wiseguysonly.com/2011/06/13/removing-tracked-files-from-git-without-deleting-them/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Astronomics &#8211; is science following the right path?</title>
		<link>http://www.wiseguysonly.com/2011/04/13/astronomics-is-science-following-the-right-path/</link>
		<comments>http://www.wiseguysonly.com/2011/04/13/astronomics-is-science-following-the-right-path/#comments</comments>
		<pubDate>Wed, 13 Apr 2011 07:25:38 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Astronomy]]></category>

		<guid isPermaLink="false">http://www.wiseguysonly.com/?p=378</guid>
		<description><![CDATA[It&#8217;s not often that Something For the Weekend - BBC2&#8242;s Sunday morning easy-watching offering &#8211;  completely changes one of my fundamental beliefs. Though that may because it&#8217;s not often that I watch it. The truth is, that had it not been for this tweet by @profbriancox, the ragged trousered cosmologist, I&#8217;d have no doubt been out [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s not often that Something For the Weekend - BBC2&#8242;s Sunday morning easy-watching offering &#8211;  completely changes one of my fundamental beliefs. Though that may because it&#8217;s not often that I watch it. The truth is, that had it not been for <a href="http://twitter.com/ProfBrianCox/status/46862357548371968">this tweet</a> by @profbriancox, the ragged trousered cosmologist, I&#8217;d have no doubt been out walking the hills. I digress.</p>
<p>You see, Brian made a statement that really hit home with me. In the midst of almost dumping the wrong ingredients into a blender he announced that there are no facts in science, only theory. And he&#8217;s right.</p>
<p>It struck a chord with me because it something I&#8217;ve been thinking about for quite some time: <em>How do we know that science is right?</em></p>
<p><em><span id="more-378"></span></em></p>
<p><em>But first some economics &#8211; it will all make sense shortly.</em></p>
<p>I studied 3 years of economics and on the whole found it pretty dry, until I got to my dissertation. Once free of the set texts, I was fortunate enough to discover evolutionary economics, and particularly the concept of path-dependency.  The skinny on path-dependency is that in progress we don&#8217;t always have the optimal, or correct solution to a problem because <em>history gets in the way</em>.</p>
<p>Here&#8217;s a quick example, then I&#8217;ll get back to <em>the science bit</em>:</p>
<p>Some time before you are reading this, thoughts have passed from my brain, through to my fingers and into the QWERTY keyboard on my netbook. Now, that same QWERTY keyboard was designed,&#8221; in part, to reduce mechanical jamming on an early typewriter design that quickly went out of use&#8221; (1).  The keys are laid out in a diagonal pattern &#8211; that is to say that they don&#8217;t fall exactly under one and other &#8211; the reason being to accommodate the key levers on early typewriters.</p>
<p>Now here&#8217;s the money shot: it&#8217;s argued (because this is only a theory) that there are  more optimal layouts for keyboards. Think about it: we certainly don&#8217;t use devices that need to prevent mechanical jamming or accomodate cumbersome levers &#8211; so why had the QWERTY layout stuck?</p>
<p>Evolutionary economists will tell you it&#8217;s down to the amount of investment in the technology. And that&#8217;s not just about the money. Think of all the training that would have to be done to get typists used to a new &#8211; albeit more efficient design. Think of all the QWERTY keyboards that are in existence.  It can be argued that the best technology (or theory) doesn&#8217;t necessarily prevail. Betamax vs. VHS anyone?</p>
<p>Let&#8217;s move away from social science, back to physical science. It was whilst reading Professor Brian Greene&#8217;s (different Professor Brian) excellent tome on string theory, almost a decade ago that I began to question the maths. There is something very beautiful about the way maths can describe our universe, but something very dangerous too.</p>
<p>String theory resonated with me when I first started reading about it. But it wasn&#8217;t without issues. But what are issues when you have the maths? It seemed that the more problems string theory came up against, the more it could beat with a few more equations and another dimension (I believe to work it requires 11 dimensions). Now I don&#8217;t doubt science is all about the maths, but I started getting the sneaky feeling we could make some pretty complex equations theorise some pretty outlandish stuff and still make accurate predictions. So long as we can get the maths to work.</p>
<p>It occurred to me that maybe string theory is just wrong. I hope not as it&#8217;s lovely. However, maybe so much time and effort (and cash) has been devoted to it that it is too hard to turn back. Moreover, if the maths keeps bringing the answers, it&#8217;s easier to keep on pushing with it. In it&#8217;s own corner of science string theory &#8211; and other prevailing theories &#8211; may have become locked-in. Path-dependent if you like.</p>
<p>But surely the best minds wouldn&#8217;t make such errors of judgement. Surely they would! Einstein termed the &#8220;cosmological constant&#8221;, a bit of maths he stuck in his equation to make it work, as the biggest mistake of his life. Turns out he didn&#8217;t need it, but nevertheless he was so locked into his line of enquiry and his belief that the universe was static that he fudged the numbers and arguably wasted the latter two decades of his life.</p>
<p>Macbeth, the competitive, but increasingly weary anti-hero of Shakespeare&#8217;s play sums it up in a darkly poetic fashion:</p>
<blockquote><p><em>&#8220;I am in blood stepped in so far that should I wade no more, Returning were as tedious as go o’er.&#8221;</em></p></blockquote>
<p>Sometimes our journey has taken us so far it&#8217;s easier to go on that turn back.</p>
<p>So can we trust science? Of course we can. The beauty of science is that it will always be theory. The important thing is that it becomes increasingly accurate at predicting things and continues to chanllenge itself.</p>
<p>Science is about fallibalism (2). It&#8217;s an infinite cycle of conjecture and testing. A good theory only needs one bad prediction and it&#8217;s out the window. But that means a great mind goes back to the start and tries again, or maybe even a greater mind finds the discarded theory and knocks it into shape.</p>
<p>There probably isn&#8217;t a right path for science. Just ones that suit the scope of our knowledge at the present time and, more importantly, make correct predictions that can be tested.</p>
<p>That is, unless of course your in a parallel universe in which case your theories may well be following a completely different line of path-dependency.</p>
<p><strong>Reference.</strong></p>
<p>1: David, Paul A. 1986. &#8220;Understanding the Economics of QWERTY: The Necessity of History.&#8221; In W.N. Parker, ed., Economic History and the Modern Economist. Oxford: Oxford University Press</p>
<p>2: Fallibalism: a definition in the Internet Encyclopedia of Philosphy <a href="http://www.iep.utm.edu/fallibil/">http://www.iep.utm.edu/fallibil/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.wiseguysonly.com/2011/04/13/astronomics-is-science-following-the-right-path/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SEO friendly URL slugs with CakePHP.</title>
		<link>http://www.wiseguysonly.com/2010/09/12/seo-friendly-url-slugs-with-cakephp/</link>
		<comments>http://www.wiseguysonly.com/2010/09/12/seo-friendly-url-slugs-with-cakephp/#comments</comments>
		<pubDate>Sun, 12 Sep 2010 19:58:03 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[Information Architecture]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.wiseguysonly.com/?p=354</guid>
		<description><![CDATA[The CakePHP framework API is a treasure trove of often undiscovered methods and functionality. Recently I came across the Inflector Class methods and noticed the &#8220;slug&#8221; method close to the bottom of the documentation, which is documented thus: Returns a string with all spaces converted to underscores (by default), accented characters converted to non-accented characters, [...]]]></description>
			<content:encoded><![CDATA[<p>The CakePHP framework API is a treasure trove of often undiscovered methods and functionality. Recently I came across the Inflector Class methods and noticed the &#8220;slug&#8221; method close to the bottom of the documentation, which is documented thus:</p>
<blockquote><p>Returns a string with all spaces converted to underscores (by default), accented characters converted to non-accented characters, and non word characters removed.</p></blockquote>
<p><span id="more-354"></span>Slug is the perfect method for generating a search engine friendly URL from any string. For instance in an application I am currently developing there is a categories model with a field called title. This makes a great field to automagically convert to a url part for SEO purposes. Now instead of a URL like <code>/category/browse/1</code> ; I can have something like <code>/category/browse/1/restauraunts-cafes-and-bars</code>.</p>
<p>For my taste of URL structure slug doesn&#8217;t work perfectly out of the box: it uses underscores to seperate words, rather than hypens; and it doesn&#8217;t convert all characters to lower-case. Having said that, a workable solutions is never far away in CakePHP.</p>
<p>The easiest solution for me is to build a reusable method in my /app/controllers/app_controller.php that I can access from any other controller or view. This way I can create a slug on the fly in my view or commit them to my database on create or update. So, let me introduce my hyper-simple private method, toSlug() :</p>
<p><code>function _toSlug($string) {<br />
return low(Inflector::slug($string, '-''));<br />
}<br />
</code><br />
Call this method like this:</p>
<p><code>$this-&gt;_toSlug("Any String or Data You like")</code></p>
<p>Which returns <code>any-string-or-data-you-like</code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.wiseguysonly.com/2010/09/12/seo-friendly-url-slugs-with-cakephp/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>CakePHP Full Text Search</title>
		<link>http://www.wiseguysonly.com/2010/06/20/cakephp-full-text-search/</link>
		<comments>http://www.wiseguysonly.com/2010/06/20/cakephp-full-text-search/#comments</comments>
		<pubDate>Sun, 20 Jun 2010 17:12:02 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[Information Architecture]]></category>
		<category><![CDATA[Personal]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://www.wiseguysonly.com/?p=346</guid>
		<description><![CDATA[CakePHP&#8217;s database abstraction is just one of the reasons to use this powerful framework for agile web development. However, it is not always obvious how to build complex queries. I recently had to implement a MySQL full text search against a music database that searched on titles, descriptions and tags. Full text search is a [...]]]></description>
			<content:encoded><![CDATA[<p>CakePHP&#8217;s database abstraction is just one of the reasons to use this powerful framework for agile web development. However, it is not always obvious how to build complex queries. I recently had to implement a MySQL full text search against a music database that searched on titles, descriptions and tags. Full text search is a quick, and not too dirty way to make a pretty decent search, although it does come with a caveat, as described in the MySQL documentation:</p>
<blockquote><p>Full-text indexes can be used only with <code style="outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: white; color: #026789; font-weight: bold; font-family: courier, 'courier new', fixed, monospace; background-position: initial initial; background-repeat: initial initial; padding: 0px; margin: 0px; border: 0px initial initial;">MyISAM</code> tables, and can be created only for <a style="outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 14px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; text-decoration: underline; color: #00759f; background-position: initial initial; background-repeat: initial initial; padding: 0px; margin: 0px; border: 0px initial initial;" title="10.4.1. The CHAR and         VARCHAR Types" href="http://dev.mysql.com/doc/refman/4.1/en/char.html"><code style="outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: white; color: #026789; font-weight: bold; font-family: courier, 'courier new', fixed, monospace; text-decoration: underline; background-position: initial initial; background-repeat: initial initial; padding: 0px; margin: 0px; border: 0px initial initial;">CHAR</code></a>, <a style="outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 14px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; text-decoration: underline; color: #00759f; background-position: initial initial; background-repeat: initial initial; padding: 0px; margin: 0px; border: 0px initial initial;" title="10.4.1. The CHAR and         VARCHAR Types" href="http://dev.mysql.com/doc/refman/4.1/en/char.html"><code style="outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: white; color: #026789; font-weight: bold; font-family: courier, 'courier new', fixed, monospace; text-decoration: underline; background-position: initial initial; background-repeat: initial initial; padding: 0px; margin: 0px; border: 0px initial initial;">VARCHAR</code></a>, or <a style="outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 14px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; text-decoration: underline; color: #00759f; background-position: initial initial; background-repeat: initial initial; padding: 0px; margin: 0px; border: 0px initial initial;" title="10.4.3. The BLOB and         TEXT Types" href="http://dev.mysql.com/doc/refman/4.1/en/blob.html"><code style="outline-width: 0px; outline-style: initial; outline-color: initial; font-size: 13px; vertical-align: baseline; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: white; color: #026789; font-weight: bold; font-family: courier, 'courier new', fixed, monospace; text-decoration: underline; background-position: initial initial; background-repeat: initial initial; padding: 0px; margin: 0px; border: 0px initial initial;">TEXT</code></a>columns.</p></blockquote>
<p><span id="more-346"></span>It did take a little bit of experimentation to get the syntax for the query correct in CakePHP as the query is a little different from the regular &#8220;<em>SELECT field FROM table WHERE somevalue = somevalue</em>&#8220;.</p>
<p>So, for this example I will use a MyISAM table called pages and search against the title, content and tags fields for the term&#8221; jquery web development&#8221;. You should substitute that term with your dynamically passed value in the code below.</p>
<p>Firstly I built the conditions for my query into a &#8220;params&#8221; array.</p>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">$params['conditions'] = array(</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space: pre;"> </span> &#8216;MATCH(Track.title,Track.description,Track.tags)</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space: pre;"> </span> AGAINST(&#8220;&#8216; . $kw_list . &#8216;&#8221; IN BOOLEAN MODE)&#8217;</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space: pre;"> </span> );</div>
<blockquote><p>$params= array(&#8216;conditions&#8217; =&gt; array(<br />
&#8216;MATCH(Page.title,Page.description,Page.tags)<br />
AGAINST(&#8220;jquery web development&#8221; )&#8217; ));</p></blockquote>
<p>Finally a call to CakePHP&#8217;s native find method will perform the search:</p>
<blockquote><p>$this-&gt;Page-&gt;find(&#8216;all&#8217;,$params);</p></blockquote>
<p>One last note: MySQL full text search can be powerful when used correctly and a potential bottleneck when poorly implemented. I suggest reading <a href="http://dev.mysql.com/doc/refman/5.1/en/fulltext-boolean.html">the documentation</a> for further information and more advanced usage.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.wiseguysonly.com/2010/06/20/cakephp-full-text-search/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to fix the OSX Leopard Set up Assistant Loop Bug.</title>
		<link>http://www.wiseguysonly.com/2010/01/19/how-to-fix-the-osx-leopard-set-up-assistant-loop-bug/</link>
		<comments>http://www.wiseguysonly.com/2010/01/19/how-to-fix-the-osx-leopard-set-up-assistant-loop-bug/#comments</comments>
		<pubDate>Tue, 19 Jan 2010 17:04:30 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Personal]]></category>

		<guid isPermaLink="false">http://www.wiseguysonly.com/?p=322</guid>
		<description><![CDATA[Today, my G5 (Leopard) started displaying the Set Up Assistant everytime it booted. Even after completing setup it was impossible to access the GUI. It was held in a continuous. If you get caught in the Leopard Setup Assistant Loop Bug, here is the way to get your Mac booting again with no loss of [...]]]></description>
			<content:encoded><![CDATA[<p>Today, my G5 (Leopard) started displaying the Set Up Assistant everytime it booted. Even after completing setup it was impossible to access the GUI. It was held in a continuous.</p>
<p>If you get caught in the Leopard Setup Assistant Loop Bug, here is the way to get your Mac booting again with no loss of data.</p>
<ol>
<li>Boot into Safe Mode by holding down the shift key just after you hear the first boot sound. This takes an eternity so be patient.</li>
<li><strong>Don&#8217;t log in to any account. Instead press the back arrow key once </strong>(this will highlight an account)<strong>.</strong></li>
<li>Then click the restart button.</li>
<li>Now just wait while your Mac performs some updates and then reboots as normal again.</li>
</ol>
<p>Even Macs break occasionally / rarely.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.wiseguysonly.com/2010/01/19/how-to-fix-the-osx-leopard-set-up-assistant-loop-bug/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

