<?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>Darren Nolan &#187; Programming</title>
	<atom:link href="http://darrennolan.com/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://darrennolan.com</link>
	<description>Computer Tech... and stuff</description>
	<lastBuildDate>Sun, 25 Mar 2012 23:32:48 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>CodeIgniter Model Validation and Rule Sets</title>
		<link>http://darrennolan.com/2012/02/12/codeigniter-model-validation-and-rule-sets/</link>
		<comments>http://darrennolan.com/2012/02/12/codeigniter-model-validation-and-rule-sets/#comments</comments>
		<pubDate>Sun, 12 Feb 2012 07:28:46 +0000</pubDate>
		<dc:creator>Dazz</dc:creator>
				<category><![CDATA[CodeIgniter]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://darrennolan.com/?p=1023</guid>
		<description><![CDATA[Update 1.0.3 19/02/12: Updated checking for validation variables and methods before calling them. Update 1.0.2 14/02/12: Removed static from libraries context. Might add static support later. Update 1.0.1 13/02/12: Changed so CI Form_Validation rules are run first. So, once again been tasked to play with the mighty CodeIgniter and having myself some fun. Except I [...]]]></description>
			<content:encoded><![CDATA[<p><strong>
Update 1.0.3 19/02/12: Updated checking for validation variables and methods before calling them.<br>
Update 1.0.2 14/02/12: Removed static from libraries context. Might add static support later.<br>
Update 1.0.1 13/02/12: Changed so CI Form_Validation rules are run first.
</strong></p>

<p>So, once again been tasked to play with the mighty <a href="http://codeigniter.com/" target="_blank">CodeIgniter</a> and having myself some fun.  Except I still don't, for the love of god, understand why default validation is defined within controllers and not the models you're about to play with.</p>

<p>And so, I present some simple awesomeness to do two things.</p>

<p>Firstly we can define Form Validation rules within our Model class.  Secondly, we can do all custom callbacks or complex rules within the model as well. So under application/models/User.php</p>
<pre class="brush: php; title: ; notranslate">
class User extends Model
{
    // Required to store Form_validation error Messages in.
    public $model_validate_error;
    
    // When declared $model_validate_&lt;fieldname&gt; will add additional rules
    public $model_validate_username = 'required|min_length[10]|max_length[50]';
    
    // Rest of your model logic here.  This will even work awesomely with PHPActiveRecord
    //
    //

    public function model_validate_username($string)
    {
        if (!validate_string_length_between($string, 4, 15)) {
            $this-&gt;model_validate_error = 'Username not between 4 and 15 characters';
            return FALSE;
        } else {
            return TRUE;
        }
    }
}
</pre>

<p>So here we're defining the rules for "username" and these are normal CodeIgniter Form_validation rules.  To create custom functions (or callbacks within the model itself) you can use the public static function model_validate_<fieldname>.  Do your logic within that function, set the validation error message if you have one, and return true/false.  validate_string_length_between() was a little testing function I added to the bottom of my form validation extender, just cause.</p>

<p>Within your controller application/controllers/signup.php for exmaple</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Signup extends MY_Controller
{
    function index()
    {
        $this-&gt;load-&gt;library('form_validation');
        
        $this-&gt;load-&gt;model('User');  // Loading for model here for validation is not required, but I assume right after validation passed you'll be saving stuff.
        
        // Call validate_model functions in the [Modelname.field] style (sort of like is_unique for table checking)
        $this-&gt;form_validation-&gt;set_rules('username', 'Username', 'validate_model[User.username]');
        $this-&gt;form_validation-&gt;set_rules('password', 'Password', 'validate_model[User.password]');
        $this-&gt;form_validation-&gt;set_rules('email', 'Email Address', 'validate_model[User.email]');
        
        if ($this-&gt;form_validation-&gt;run()) {
            $this-&gt;view_data['message'] = &quot;pass&quot;;
        } elseif ($this-&gt;input-&gt;post()) {
            $this-&gt;view_data['message'] = &quot;failed&quot;;
        } else {
            $this-&gt;view_data['message'] = &quot;not run&quot;;
        }
    }
}
</pre>

<p>One nice thing is that even after you declare validate_model on the email field, you don't need the rules already saved in the Model nor the extended callback function there.  If it's there, it will be used.  If it's not, it won't.  Means you can setup your controllers today, and populate the rules tomorrow.</p>

<p>Your extending function application/libraries/MY_Form_validation.php</p>

<pre class="brush: php; title: ; notranslate">
&lt;?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
 
class MY_Form_validation extends CI_Form_validation
{
     
    public function set_rules($field, $label = '', $rules = '')
    {
        // Check if &quot;validate_model&quot; is a rule within our set of rules.  If it is, load up the model's rules
        // within the rule-set and continue on to CI's class.
         
        if (strlen($rules) != 0) {
            $rule_list = explode('|', $rules);
            if ($rule_list != FALSE) {
                foreach ($rule_list as $rule) {
                    if (substr($rule, 0, 15) == 'validate_model[') {
                        // Found a validate_model ruling.  Grab the class name and field type.
                        $rule = substr($rule, 15);
                        $rule = substr($rule, 0, -1);
                        $functionName = explode ('.', $rule);
                        if (count($functionName == 2)) {
                            $modelName = $functionName[0];
                            $variableName = 'model_validate_' . $functionName[1];
                            
                            $this-&gt;CI-&gt;load-&gt;model($modelName, 'validate_model'); // Load the model
                            
                            if (isset($this-&gt;CI-&gt;validate_model-&gt;$variableName)) {
                                $rules = $this-&gt;CI-&gt;validate_model-&gt;$variableName . '|' . $rules;
                            }
                        }
                    }
                }
            }
        }
        // Always continue with the default CI set_rules even if we can't work anything additional out.
        parent::set_rules($field, $label, $rules);
    }
     
    public function validate_model($input = FALSE, $model_field = FALSE)
    {
        $functionName = explode('.', $model_field);
        if (count($functionName) != 2) {
            // Unable to work out 'model.function' to call.
            return;
        }
         
        $modelName = $functionName[0];
        $methodName = 'model_validate_' . $functionName[1];
         
        $this-&gt;CI-&gt;load-&gt;model($modelName, 'validate_model'); // Load the model if it's not already loaded.
         
        if (method_exists($this-&gt;CI-&gt;validate_model, $methodName)) {
            //$result = call_user_func(array($modelName, $methodName), $input);
            $result = $this-&gt;CI-&gt;validate_model-&gt;$methodName($input);
            if ($result) {
                return TRUE;
            } else {
                $this-&gt;set_message(&quot;validate_model&quot;, $this-&gt;CI-&gt;validate_model-&gt;model_validate_error);
                $this-&gt;CI-&gt;validate_model-&gt;model_validate_error = NULL;
                return FALSE;
            }
        } else {
            log_message('debug', &quot;Unable to find validation rule: $modelName -&gt; $methodName&quot;);
            return;
        }
    }
}

// Validation Functions
if (!function_exists('validate_string_length_between')) {
    function validate_string_length_between($string, $min, $max)
    {
        if (strlen($string) &gt;= $min AND strlen($string) &lt;= $max) {
            return TRUE;
        } else {
            return FALSE;
        }
    }
}
</pre>

<p>So!  I hope with this simple stuff, makes your controllers much neater, and rules and validation far more reusable than either saving your rules in a config file, or copy/pasting your rules between controllers and extending Form_validation with custom function callbacks.</p>

<p>Feedback welcome, let me know!</p>]]></content:encoded>
			<wfw:commentRss>http://darrennolan.com/2012/02/12/codeigniter-model-validation-and-rule-sets/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>cPanel + Redmine 1.2.1 &#8211; Pages delivered as text/plain when using rewrite</title>
		<link>http://darrennolan.com/2011/10/10/cpanel-redmine-1-2-1-pages-delivered-as-textplain-when-using-rewrite/</link>
		<comments>http://darrennolan.com/2011/10/10/cpanel-redmine-1-2-1-pages-delivered-as-textplain-when-using-rewrite/#comments</comments>
		<pubDate>Mon, 10 Oct 2011 08:38:52 +0000</pubDate>
		<dc:creator>Dazz</dc:creator>
				<category><![CDATA[cPanel]]></category>
		<category><![CDATA[Redmine]]></category>

		<guid isPermaLink="false">http://darrennolan.com/?p=1008</guid>
		<description><![CDATA[Well. Bit more of a trouble than I wish to deal with today, but apparently Mongrel has changed somewhat in the latest version and doesn't deliver content as HTML, instead delivering it as text/plain (source html). If you are using Mongrel to deliver your Ruby Apps, and you're sure your versions of gems meet the [...]]]></description>
			<content:encoded><![CDATA[<p>Well.</p>

<p>Bit more of a trouble than I wish to deal with today, but apparently Mongrel has changed somewhat in the latest version and doesn't deliver content as HTML, instead delivering it as text/plain (source html).</p>

<p>If you are using Mongrel to deliver your Ruby Apps, and you're <strong>sure</strong> your versions  of gems meet the <a href="http://www.redmine.org/projects/redmine/wiki/RedmineInstall#Compatibility-notes" target="_blank">requirements </a> - take a look at the below to try.</p>

<p>Add this file in, restart your application - and hopefully away you go.  Again there is a lot of read/take in when it comes to dealing with this issue - hopefully I'm saving you about 1.5 hours of <a href="https://rails.lighthouseapp.com/projects/8994/tickets/4690#ticket-4690-23" target="_blank">research.</a> <a href="https://gist.github.com/471663" target="_blank">Original Source for the Patch I've forked.</a>.</p>

<p>Add this to redmine/config/initializers/mongrel.rb (create a new file)</p>
<pre class="brush: ruby; title: ; notranslate">
# Pulled right from latest rack. Old looked like this in 1.1.0 version.
  # 
  # def [](k)
  #   super(@names[k] ||= @names[k.downcase])
  # end
  # 
  module Rack
    module Utils
      class HeaderHash &lt; Hash
        def [](k)
          super(@names[k]) if @names[k]
          super(@names[k.downcase])
        end
      end
    end
  end
  
  # Code pulled from the ticket above.
  # 
  class Mongrel::CGIWrapper
    def header_with_rails_fix(options = 'text/html')
      @head['cookie'] = options.delete('cookie').flatten.map { |v| v.sub(/^\n/,'') } if options.class != String and options['cookie']
      header_without_rails_fix(options)
    end
    alias_method_chain :header, :rails_fix
  end
  
  # Pulled right from 2.3.8 ActionPack. Simple diff was
  # 
  # if headers.include?('Set-Cookie')
  #   headers['cookie'] = headers.delete('Set-Cookie').split(&quot;\n&quot;)
  # end
  # 
  # to 
  # 
  # if headers['Set-Cookie']
  #   headers['cookie'] = headers.delete('Set-Cookie').split(&quot;\n&quot;)
  # end
  #       
  module ActionController
    class CGIHandler
      def self.dispatch_cgi(app, cgi, out = $stdout)
        env = cgi.__send__(:env_table)
        env.delete &quot;HTTP_CONTENT_LENGTH&quot;
        cgi.stdinput.extend ProperStream
        env[&quot;SCRIPT_NAME&quot;] = &quot;&quot; if env[&quot;SCRIPT_NAME&quot;] == &quot;/&quot;
        env.update({
          &quot;rack.version&quot; =&gt; [0,1],
          &quot;rack.input&quot; =&gt; cgi.stdinput,
          &quot;rack.errors&quot; =&gt; $stderr,
          &quot;rack.multithread&quot; =&gt; false,
          &quot;rack.multiprocess&quot; =&gt; true,
          &quot;rack.run_once&quot; =&gt; false,
          &quot;rack.url_scheme&quot; =&gt; [&quot;yes&quot;, &quot;on&quot;, &quot;1&quot;].include?(env[&quot;HTTPS&quot;]) ? &quot;https&quot; : &quot;http&quot;
        })
        env[&quot;QUERY_STRING&quot;] ||= &quot;&quot;
        env[&quot;HTTP_VERSION&quot;] ||= env[&quot;SERVER_PROTOCOL&quot;]
        env[&quot;REQUEST_PATH&quot;] ||= &quot;/&quot;
        env.delete &quot;PATH_INFO&quot; if env[&quot;PATH_INFO&quot;] == &quot;&quot;
        status, headers, body = app.call(env)
        begin
          out.binmode if out.respond_to?(:binmode)
          out.sync = false if out.respond_to?(:sync=)
          headers['Status'] = status.to_s
          if headers['Set-Cookie']
            headers['cookie'] = headers.delete('Set-Cookie').split(&quot;\n&quot;)
          end
          out.write(cgi.header(headers))
          body.each { |part|
            out.write part
            out.flush if out.respond_to?(:flush)
          }
        ensure
          body.close if body.respond_to?(:close)
        end
      end
    end
  end
</pre>


]]></content:encoded>
			<wfw:commentRss>http://darrennolan.com/2011/10/10/cpanel-redmine-1-2-1-pages-delivered-as-textplain-when-using-rewrite/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL: Return dates between two dates &#8211; Make Intervals Procedure</title>
		<link>http://darrennolan.com/2011/09/06/mysql-return-dates-between-two-dates-make-intervals-procedure/</link>
		<comments>http://darrennolan.com/2011/09/06/mysql-return-dates-between-two-dates-make-intervals-procedure/#comments</comments>
		<pubDate>Tue, 06 Sep 2011 03:13:55 +0000</pubDate>
		<dc:creator>Dazz</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://darrennolan.com/?p=959</guid>
		<description><![CDATA[Full credit to Ron Savage over at Stack Exchange. He's written this fantastic function which creates a temporary table with two columns, 'interval_start' and 'interval_end'. You call this function with a MySQL datetime ('2011-02-23 05:00:00'), and a MySQL end datetime ('2011-02-23 16:00:00'). You then specify what you want returned back to you (Seconds, Minutes, Hours, [...]]]></description>
			<content:encoded><![CDATA[<p>Full credit to <strong><a href="http://www.dot-dash-dot.com/" target="_blank">Ron Savage</a></strong> over at <a href="http://stackoverflow.com/users/12476/ron-savage" target="_blank">Stack Exchange</a>.  He's written this fantastic function which creates a temporary table with two columns, 'interval_start' and 'interval_end'.</p>

<p>You call this function with a MySQL datetime (<em>'2011-02-23 05:00:00'</em>), and a MySQL end datetime (<em>'2011-02-23 16:00:00'</em>).  You then specify what you want returned back to you (<em>Seconds, Minutes, Hours, Days etc. See the function below for the full list of options</em>).</p>

<p>What is returned is below will be similar;</p>
<table>
	<tr>
		<th>interval_start</th>
		<th>interval_end</th>
	</tr>
	<tr>
		<td>2011-02-23 05:00:00</td>
		<td>2011-02-23 05:59:59</td>
	</tr>
	<tr>
		<td>2011-02-23 06:00:00</td>
		<td>2011-02-23 06:59:59</td>
	</tr>
	<tr>
		<td>2011-02-23 07:00:00</td>
		<td>2011-02-23 07:59:59</td>
	</tr>
	<tr>
		<td>2011-02-23 08:00:00</td>
		<td>2011-02-23 08:59:59</td>
	</tr>
	<tr>
		<td>2011-02-23 09:00:00</td>
		<td>2011-02-23 09:59:59</td>
	</tr>
	<tr>
		<td>2011-02-23 10:00:00</td>
		<td>2011-02-23 10:59:59</td>
	</tr>
	<tr>
		<td>2011-02-23 11:00:00</td>
		<td>2011-02-23 11:59:59</td>
	</tr>
	<tr>
		<td>2011-02-23 12:00:00</td>
		<td>2011-02-23 12:59:59</td>
	</tr>
	<tr>
		<td>2011-02-23 13:00:00</td>
		<td>2011-02-23 13:59:59</td>
	</tr>
	<tr>
		<td>2011-02-23 14:00:00</td>
		<td>2011-02-23 14:59:59</td>
	</tr>
	<tr>
		<td>2011-02-23 15:00:00</td>
		<td>2011-02-23 15:59:59</td>
	</tr>
</table>
<span id="more-959"></span>
<p>And his fantastic function is below!</p>
<pre class="brush: sql; title: ; notranslate">
DELIMITER //;

CREATE PROCEDURE make_intervals(startdate timestamp, enddate timestamp, intval integer, unitval varchar(10))
BEGIN
-- *************************************************************************
-- Procedure: make_intervals()
--    Author: Ron Savage
--      Date: 02/03/2009
--
-- Description:
-- This procedure creates a temporary table named time_intervals with the
-- interval_start and interval_end fields specifed from the startdate and
-- enddate arguments, at intervals of intval (unitval) size.
-- *************************************************************************
   declare thisDate timestamp;
   declare nextDate timestamp;
   set thisDate = startdate;

   -- *************************************************************************
   -- Drop / create the temp table
   -- *************************************************************************
   drop temporary table if exists time_intervals;
   create temporary table if not exists time_intervals
      (
      interval_start timestamp,
      interval_end timestamp
      );

   -- *************************************************************************
   -- Loop through the startdate adding each intval interval until enddate
   -- *************************************************************************
   repeat
      select
         case unitval
            when 'MICROSECOND' then timestampadd(MICROSECOND, intval, thisDate)
            when 'SECOND'      then timestampadd(SECOND, intval, thisDate)
            when 'MINUTE'      then timestampadd(MINUTE, intval, thisDate)
            when 'HOUR'        then timestampadd(HOUR, intval, thisDate)
            when 'DAY'         then timestampadd(DAY, intval, thisDate)
            when 'WEEK'        then timestampadd(WEEK, intval, thisDate)
            when 'MONTH'       then timestampadd(MONTH, intval, thisDate)
            when 'QUARTER'     then timestampadd(QUARTER, intval, thisDate)
            when 'YEAR'        then timestampadd(YEAR, intval, thisDate)
         end into nextDate;

      insert into time_intervals select thisDate, timestampadd(MICROSECOND, -1, nextDate);
      set thisDate = nextDate;
   until thisDate &gt;= enddate
   end repeat;

 END//
</pre>
<p>So to run the query, you'd basically call it with the following 
<pre class="brush: sql; title: ; notranslate">
CALL make_intervals(('2011-02-23 10:00:00' - INTERVAL 5 HOUR),('2011-02-23 10:00:00' + INTERVAL 6 HOUR),1,'HOUR');
SELECT * FROM time_intervals;
</pre>
<p>So why would you do this?  Depending on what you're working with, you could start to produce results for a month worth of sales for example, but rather than have program fill in the blanks for all the days that are missing and have no sales, join the sales (and allow NULL or 0 results from these sales) to this temporary table.</p>
<p>In my use for a mate's horrible exercise, the data he was using was simply... "holely", and while we weren't in a position to fix the data we had, using this simply allowed us to pull in available data using LEFT JOIN and allowing NULLS to be returned to us.</p>
<p>It's far easier to have MySQL do the leg work for you, rather than to gather the data that is available (<em>in 18 MySQL statements...</em>) and walk through your array of results, moving only onto the next index of the array when you find acceptable data.  Which needless to say, was incredibly bulky in terms of PHP, ugly and what I would define as unmanageable!</p>

<p><strong>So in conclusion!</strong>  Huge thanks to Ron, this function in my opinion is extremely useful, and I hope others find it as useful as I have</p>]]></content:encoded>
			<wfw:commentRss>http://darrennolan.com/2011/09/06/mysql-return-dates-between-two-dates-make-intervals-procedure/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>PHP and HTML &#8211; Keep it clean, keep it separate</title>
		<link>http://darrennolan.com/2011/09/01/php-and-html-keep-it-clean-keep-it-separate/</link>
		<comments>http://darrennolan.com/2011/09/01/php-and-html-keep-it-clean-keep-it-separate/#comments</comments>
		<pubDate>Thu, 01 Sep 2011 06:11:04 +0000</pubDate>
		<dc:creator>Dazz</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://darrennolan.com/?p=927</guid>
		<description><![CDATA[I've been helping out of couple of friends with their University assignments recently and one thing that has bugged me to no end, is how they're not being shown how to keep code clean and manageable. Take the following example (which is close to what their University lecture's have been giving out as an example). Without [...]]]></description>
			<content:encoded><![CDATA[<p>I've been helping out of couple of friends with their University assignments recently and one thing that has bugged me to no end, is how they're not being shown how to keep code clean and manageable.</p>

<p>Take the following example (which is close to what their University lecture's have been giving out as an example).</p>

<pre class="brush: php; title: ; notranslate">
&lt;?php
	$fruitArray	= array(
					&quot;apple&quot; =&gt; &quot;green&quot;,
					&quot;tomato&quot; =&gt; &quot;red&quot;, 
					&quot;banana&quot; =&gt; &quot;yellow&quot;, 
					&quot;grape&quot; =&gt; &quot;purple&quot;, 
					&quot;orange&quot; =&gt; &quot;orange&quot;);
	
	echo &quot;&lt;table&gt;&quot;;
	echo &quot;&lt;tr&gt;&quot;;
	echo &quot;&lt;th&gt;Fruit&lt;/th&gt;&quot;;
	echo &quot;&lt;th&gt;Colour&lt;/th&gt;&quot;;
	echo &quot;&lt;/tr&gt;&quot;;
	ksort($fruitArray);
	foreach ($fruitArray as $fruit =&gt; $colour) {
		echo &quot;&lt;tr&gt;&quot;;
		echo &quot;&lt;td&gt;&quot; . $fruit . &quot;&lt;/td&gt;&quot;;
		echo &quot;&lt;td&gt;&quot; . $colour . &quot;&lt;/td&gt;&quot;;
		echo &quot;&lt;/tr&gt;&quot;;
	}
	echo &quot;&lt;/table&gt;&quot;;
?&gt;
</pre>
<span id="more-927"></span>
<p>Without going into too much detail, it's generally a <strong>terrible</strong> idea to be echo-ing HTML code in this way.  More pressing than just losing HTML syntax highlighting in your preferred editor, keep track of tabulation in your HTML code is now non existent, although you could add tabs within the quotes - it's simply going to end up far more messy than before.  You've also lost your line-breaks between elements.  Not a huge issue, but when you start to view the source of your page for debugging purposes - everything is going to be spit out on one long line.  Again, you can counter this by adding "\n" to the end of your strings - but we're slowly getting out of control for some basic code management.</p>

<p>It's my opinion, that you should firstly keep your logic well separated from your HTML.  In this example, array sorting should be done before you start print HTML.  You should learn the <a href="http://php.net/manual/en/control-structures.alternative-syntax.php" target="_blank">alternative syntax structure</a> for 'if', 'foreach' and 'while' statements.</p>
<p>Where possible (server allowing, and you can add your own .htaccess file if your university has turned off most things) - use shortform PHP statements.  That is, instead of &lt;?php echo $title; ?&gt;, try using the much smaller &lt;?=$title;?&gt;</p>

<p>Let's try again.</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php
	$fruitArray	= array(
					&quot;apple&quot; =&gt; &quot;green&quot;, 
					&quot;tomato&quot; =&gt; &quot;red&quot;, 
					&quot;banana&quot; =&gt; &quot;yellow&quot;, 
					&quot;grape&quot; =&gt; &quot;purple&quot;, 
					&quot;orange&quot; =&gt; &quot;orange&quot;);
	ksort($fruitArray);
	
	// Any other form of math or logic to go here.
?&gt;

&lt;!-- From this point onwards, we're mostly HTML now --&gt;
&lt;table&gt;
	&lt;tr&gt;
		&lt;th&gt;Fruit&lt;/th&gt;
		&lt;th&gt;Colour&lt;/th&gt;
	&lt;/tr&gt;
	&lt;?foreach ($fruitArray as $fruit =&gt; $color):?&gt;
	&lt;tr&gt;
		&lt;td&gt;&lt;?=$fruit;?&gt;&lt;/td&gt;
		&lt;td&gt;&lt;?=$color;?&gt;&lt;/td&gt;
	&lt;/tr&gt;
	&lt;?endforeach;?&gt;
&lt;/table&gt;
</pre>

<p>Already we've made this much easier to manage because our logic is quite seperate from the HTML we're displaying.  We're still able to do loops using the alternative syntax mentioned earlier which allows us to use foreach(): and endforeach; rather than keeping track of opening and closing brackets.</p>

<p>And if you don't have PHP short tags enabled on your server (yes you James), ensure you replace '&lt;?=' with '&lt;?php echo '.  But that will still keep your code extremely clean and manageable.</p>]]></content:encoded>
			<wfw:commentRss>http://darrennolan.com/2011/09/01/php-and-html-keep-it-clean-keep-it-separate/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>WordPress from a subdirectory served from a domain root</title>
		<link>http://darrennolan.com/2011/07/01/wordpress-from-a-subdirectory-served-from-a-domain-root/</link>
		<comments>http://darrennolan.com/2011/07/01/wordpress-from-a-subdirectory-served-from-a-domain-root/#comments</comments>
		<pubDate>Thu, 30 Jun 2011 15:18:33 +0000</pubDate>
		<dc:creator>Dazz</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://darrennolan.com/?p=799</guid>
		<description><![CDATA[So the dilemma rose tonight when James wanted WordPress installed on his domain that he&#8217;s had since the dawn of time.  Awesome I say!  How exciting!  Get the zip, unzip it, set it up and go for it. Well after fighting with Dreamhost for a little while on setting up new SQL database, I discovered [...]]]></description>
			<content:encoded><![CDATA[<p>So the dilemma rose tonight when James wanted WordPress installed on his domain that he&#8217;s had since the dawn of time.  Awesome I say!  How exciting!  Get the zip, unzip it, set it up and go for it.</p>
<p>Well after fighting with Dreamhost for a little while on setting up new SQL database, I discovered there&#8217;s 5+ years worth of junk sitting in his root public html directory.  &#8221;K dude, I&#8217;m just going to move these to a subdomain files. and you can start using that&#8221;.  Well, after posting for 5 years of links around the internet &#8211; he didn&#8217;t like that idea.</p>
<p>So I had this fantastic idea &#8211; install WordPress in a subdirectory and I&#8217;m sure we can find some .htaccess rewrite rules to compensate.  Turns out, it doesn&#8217;t appear to be a popular topic on the web.</p>
<p><span id="more-799"></span>So, after hours of fighting with the world &#8211; the hacked solution is below.  It&#8217;s dreadfully important that you have some sort of SEO friendly (permalinks) turned on <strong>before </strong>you start using these rules.</p>
<pre lang="language">RewriteEngine On
RewriteBase /

RewriteRule ^$ /wordpress/index.php [L]

RewriteRule ^wp-login.php$ wordpress/wp-login.php [L]
RewriteRule ^wp-comments-post.php$ wordpress/wp-comments-post.php [L]
RewriteRule ^wp-register.php$ wordpress/wp-register.php [L]
RewriteRule ^wp-rss2.php$ wordpress/wp-rss2.php [L]
RewriteRule ^wp-atom.php$ wordpress/wp-atom.php [L]
RewriteRule ^wp-pass.php$ wordpress/wp-pass.php [L]
RewriteRule ^wp-rss.php$ wordpress/wp-rss.php [L]
RewriteRule ^wp-commentsrss2.php$ wordpress/wp-commentsrss2.php [L]
RewriteRule ^wp-feed.php$ wordpress/wp-feed.php [L]
RewriteRule ^wp-signup.php$ wordpress/wp-signup.php [L]
RewriteRule ^wp-trackback.php$ wordpress/wp-trackback.php [L]
RewriteRule ^wp-activate.php$ wordpress/wp-activate.php [L]
RewriteRule ^wp-links-opml.php$ wordpress/wp-links-opml.php [L]
RewriteRule ^wp-rdf.php$ wordpress/wp-rdf.php [L]

RewriteRule ^wp-admin/(.*)$ wordpress/wp-admin/$1 [L]
RewriteRule ^wp-content/(.*)$ wordpress/wp-content/$1 [L]
RewriteRule ^wp-includes/(.*)$ wordpress/wp-includes/$1 [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . wordpress/index.php [L]</pre>
<p>Anywhere &#8220;wordpress&#8221; is written, this is your subdomain.  I&#8217;m sure there&#8217;s 92 ways to make this far prettier, and if you know of a blog post or forum topic that talks about doing this in a better way, please by all means do give your feedback.</p>
<p>As far as I know, /wp-login.php is the only file other than index.php that&#8217;s ever called &#8211; so that is why it has a speical rule just for it.  I do suspect James will run into some pages that may require tweaking &#8211; and I&#8217;ll update this post when that day comes (if it ever comes).</p>
<p>Edit: So the first issue was that comments go back to the wp-comments.php file, so like wp-login I&#8217;ve quickly added it in, and the other files I think <em>may </em>be used.</p>
]]></content:encoded>
			<wfw:commentRss>http://darrennolan.com/2011/07/01/wordpress-from-a-subdirectory-served-from-a-domain-root/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>XAMPP, Eclipse and xDebug oh my!</title>
		<link>http://darrennolan.com/2011/05/11/xampp-eclipse-and-xdebug-oh-my/</link>
		<comments>http://darrennolan.com/2011/05/11/xampp-eclipse-and-xdebug-oh-my/#comments</comments>
		<pubDate>Wed, 11 May 2011 03:43:59 +0000</pubDate>
		<dc:creator>Dazz</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://darrennolan.com/?p=791</guid>
		<description><![CDATA[So I hope this gets into the world out there. I&#8217;m running the latest version possible of XAMPP for windows (shame on me for windows right?), Eclipse and xDebug. One interesting thing that has frustrated the absolute hell out of me while working recently is that Apache continues to fail on every breakpoint in my [...]]]></description>
			<content:encoded><![CDATA[<p>So I hope this gets into the world out there.  I&#8217;m running the latest version possible of XAMPP for windows (shame on me for windows right?), Eclipse and xDebug.</p>
<p>One interesting thing that has frustrated the absolute hell out of me while working recently is that Apache continues to fail on every breakpoint in my code.  &#8220;Apache has Stopped working&#8221;, and then silently restarts itself.</p>
<p>Sadly there is no further advise from Apache or PHP Logs even went making everything log to their fullest capacity.</p>
<p>And thus brings me to <a href="http://windows.fyicenter.com/view.php?ID=68&amp;R=71">http://windows.fyicenter.com/view.php?ID=68&amp;R=71</a> &#8211; Which is a fantastic little thing you can try on your local dev machines &#8211; which quickly and shamefully easily makes your PHP scripts run in php-cgi rather than the default setup of XAMPP.</p>
<p>I&#8217;m break-pointing again and everything is well in the land of New Zealand (Oh btw, I&#8217;m in New Zealand working my little coding ass off at the moment, should be back in the land of Oz early early June).</p>
<p>Cheers Chaps.</p>
]]></content:encoded>
			<wfw:commentRss>http://darrennolan.com/2011/05/11/xampp-eclipse-and-xdebug-oh-my/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Some interesting statistics</title>
		<link>http://darrennolan.com/2011/03/02/some-interesting-statistics/</link>
		<comments>http://darrennolan.com/2011/03/02/some-interesting-statistics/#comments</comments>
		<pubDate>Wed, 02 Mar 2011 00:24:26 +0000</pubDate>
		<dc:creator>Dazz</dc:creator>
				<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://darrennolan.com/?p=781</guid>
		<description><![CDATA[Because sharing is caring, I thought I&#8217;d take a look at (and show) the common screen resolutions and browsers of those that visit this site. I think it&#8217;s wonderful to note that while IE6 is still around kicking and screaming about on the internet (I like to believe it&#8217;s out of viewers control), only 13% [...]]]></description>
			<content:encoded><![CDATA[<p>Because sharing is caring, I thought I&#8217;d take a look at (and show) the common screen resolutions and browsers of those that visit this site.</p>
<p><a href="http://darrennolan.com/wp-content/uploads/2011/03/screenres.png" rel="lightbox[781]"><img class="aligncenter size-medium wp-image-782" title="screenres" src="http://darrennolan.com/wp-content/uploads/2011/03/screenres-300x71.png" alt="" width="300" height="71" /></a></p>
<p><a href="http://darrennolan.com/wp-content/uploads/2011/03/browsers.png" rel="lightbox[781]"><img class="aligncenter size-medium wp-image-783" title="browsers" src="http://darrennolan.com/wp-content/uploads/2011/03/browsers-300x71.png" alt="" width="300" height="71" /></a></p>
<p><a href="http://darrennolan.com/wp-content/uploads/2011/03/browsers-ie.png" rel="lightbox[781]"><img src="http://darrennolan.com/wp-content/uploads/2011/03/browsers-ie-300x71.png" alt="" title="browsers-ie" width="300" height="71" class="aligncenter size-medium wp-image-784" /></a></p>
<p>I think it&#8217;s wonderful to note that while IE6 is still around kicking and screaming about on the internet (I like to believe it&#8217;s out of viewers control), only 13% of IE users still use this version, with a great majority on IE8.  When IE9 comes out of it&#8217;s RC status into release, I think I can start to get excited.</p>
]]></content:encoded>
			<wfw:commentRss>http://darrennolan.com/2011/03/02/some-interesting-statistics/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New Custom Theme!</title>
		<link>http://darrennolan.com/2010/09/30/new-custom-theme/</link>
		<comments>http://darrennolan.com/2010/09/30/new-custom-theme/#comments</comments>
		<pubDate>Thu, 30 Sep 2010 06:59:58 +0000</pubDate>
		<dc:creator>Dazz</dc:creator>
				<category><![CDATA[Personal]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.darrennolan.com/?p=742</guid>
		<description><![CDATA[Well, what started out as a quick fiddle with CSS3 and HTML5 new elements, tags and techniques, quickly turned into my new theme here are darrennolan.com. Behold the latest of my understandings in this new exciting world!!! There is virtually no images involved with this layout, in fact I&#8217;m fairly sure there&#8217;s only one image [...]]]></description>
			<content:encoded><![CDATA[<p>Well, what started out as a quick fiddle with CSS3 and HTML5 new elements, tags and techniques, quickly turned into my new theme here are <a href="http://darrennolan.com/">darrennolan.com</a>.</p>
<p>Behold the latest of my understandings in this new exciting world!!!</p>
<p>There is virtually no images involved with this layout, in fact I&#8217;m fairly sure there&#8217;s only one image used for backwards compatibility purposes.  Most elements here use the new rounded borders of CSS3 (if you don&#8217;t see rounded stuff, you <strong>really</strong> should update your browser).</p>
<p><a href="http://darrennolan.com/wp-content/uploads/2010/09/Screenshot.png" rel="lightbox[742]"><img class="aligncenter size-medium wp-image-743" title="Screenshot" src="http://darrennolan.com/wp-content/uploads/2010/09/Screenshot-300x216.png" alt="" width="300" height="216" /></a></p>
<p>If the site looks much more &#8220;boxy&#8221;, it&#8217;s a fairly certain indication that you&#8217;ll need to update your browser.  I&#8217;m fairly sure (sorry IE users) that Internet Explorer 8 doesn&#8217;t have some of the newer fancier elements used in this design.</p>
<p>Well, I hope you like it.  I know I had an exciting time learning and using the new aspects of this awesome stuffs.  Given more time I might even share some secrets with you <img src='http://darrennolan.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://darrennolan.com/2010/09/30/new-custom-theme/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Email Contact Forms</title>
		<link>http://darrennolan.com/2010/09/03/email-contact-forms/</link>
		<comments>http://darrennolan.com/2010/09/03/email-contact-forms/#comments</comments>
		<pubDate>Fri, 03 Sep 2010 16:00:26 +0000</pubDate>
		<dc:creator>Dazz</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[mailer php]]></category>
		<category><![CDATA[message headers]]></category>
		<category><![CDATA[recaptcha]]></category>
		<category><![CDATA[sending mail]]></category>
		<category><![CDATA[x mailer]]></category>

		<guid isPermaLink="false">http://www.darrennolan.com/?p=698</guid>
		<description><![CDATA[Yet another awesome service from google. reCaptcha. More on that later.  But firstly, sending from the right address. Helping out a friend at her new(ish) job and their contact form simply sucked.  Suppose it takes a bit of a background in both PHP web coding and more so in understanding Mail protocols than anything else. [...]]]></description>
			<content:encoded><![CDATA[<p>Yet another awesome service from google. <a href="http://www.google.com/recaptcha">reCaptcha</a>. More on that later.  But firstly, sending from the right address.</p>

<p>Helping out a friend at her new(ish) job and their contact form simply sucked.  Suppose it takes a bit of a background in both PHP web coding and more so in understanding Mail protocols than anything else.</p>

<p>The first thing people really need to get out of the habit is trying to send emails as the person who wishes to contact you.  Take in this small example;</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php
	$to = 'contact@mydomain.com';
	$subject = 'Website Contact Form';
	$message = $_POST['formMessage'];
	$headers = 'From: ' . $_POST['formEmailAddress'] . &quot;\r\n&quot;;
	mail($to, $subject, $message, $headers);
?&gt;
</pre>

<p>Without getting hooked up on using raw entries from $_POST, basically the above code will take your contact details and attempt to send it to yourself.   You write into the headers that this email is coming from whatever address the user entered when filling in the form.</p>

<p>THAT'S A BIG NO NO.  More and more mail servers today (including your own, which is where some of the issue comes) checks the IP and/or domain name of where an email is being sent from, in this case it's your webserver, and looks up that domain to see if that domain or IP address is allowed to pretend to be sending mail.  I promise no one has added in your domain details to allow to send email as them.  Certainly not the bigger dogs like Bigpond, Optus etc.</p>

<p>This is just one method that checks mail servers use today to check the authenticity of mail getting into people's boxes.  Otherwise you can basically be sending mail out as Google or even PayPal.</p>

<p>Here's what you should have done when coding your contact form.</p>

<pre class="brush: php; title: ; notranslate">
&lt;?php
	$to = 'contact@mydomain.com';
	$subject = 'Website Contact Form';
	$message = $_POST['formMessage'];
	$headers = 'From: contact@mydomain.com' . &quot;\r\n&quot; .
				'Reply-To: ' . $_POST['formEmailAddress'] . &quot;\r\n&quot; .
				'X-Mailer: PHP/' . phpversion();
	mail($to, $subject, $message, $headers);
?&gt;
</pre>

<p>So how's this work now?  Basically, we're saying this email we're going to get is from our OWN domain.  However when you hit the reply to start a conversation with the user that filled in the contact form, your email client will use the details in the Reply-To.  Adding the X-Mailer section there is to let severs know that yes indeed this message has been sent from a PHP script.</p>

<p>Because your script is now sending from your website as your own email (typically where your mailserver resides) this solves some of the more common 550 errors in emails (Email error: 550 SPF: x.x.x.x is not allowed to send mail from ...)</p>

<p>Doing things properly you shouldn't stop there guys.  The really good and neat way of sending mail out of your web scripts is to connect to your mail server directly, and send it from there.  Need pear with it's mail modules installed for PHP.</p>

<p>If you don't already have this, you should lightly slap yourself and then quickly install it.</p>
<p>On Ubuntu:</p>
<pre class="brush: bash; title: ; notranslate">
sudo apt-get install php-pear
sudo pear install mail
sudo pear install Net_SMTP
sudo pear install Auth_SASL
sudo pear install mail_mime
</pre>

<p>Here's how our example would work now.</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php
	include &quot;Mail.php&quot;;
	$to = 'contact@mydomain.com';
	$headers['From']		= 'webmaster@mydomain.com';
	$headers['To']			= $to;
	$headers['Subject']		= 'Website Contact Form';
	$headers['Reply-To']	= $_POST['formName'] .
							'&lt;' .$_POST['formEmailAddress'] . '&gt;';

	$smtpinfo['host']		= 'localhost';
	$smtpinfo['port']		= '25';
	$smtpinfo['auth']		= true;
	$smtpinfo['username']	= 'my_mail_username';
	$smtpinfo['password']	= 'my_mail_password';

	$mail_message = $_POST['formMessage'];

	$mail_handler =&amp; Mail::factory(&quot;smtp&quot;, $smtpinfo);
	$mail_handler-&gt;send($to, $headers, $mail_message);
?&gt;
</pre>

<p>Naturally I'd expect you to validate your data and not just use raw data sent from the browser, but this will connect up to a SMTP server and send it off via that server (which lets your messages get signed by a range of other anti-spam measures in place today).</p>

<p>If you require an SSL connection to your mail server (for example, google handles your mail for you (like it does for me)) you can change the host to "ssl://hostname" and the Mail package will work it out from there.  Sadly it's not shown on the documentation about that handy little trick on the Pear page.</p>

<p>Another alternative is using sockets directly, which is fantastic and awesomes (and doesn't require Pear/Mail), and you can find a heap of PHP Libraries out there to give you access to do so.  Personally I'm a bit of a fan of <a href="http://codeigniter.com/">CodeIgniter</a> and has these sorts of things built in already.  Epic win.</p>

<p><strong>GETTING SIDE TRACK HERE</strong>, but hopefully you'll start to use a neater way of sending your contact form messages out now.</p>

<p>Google reCaptcha adds that (sometimes) annoying little image to forms before you get to fill them in.  Basically ensuring you're human and not some spam bot with insecurities about it's epen requiring extensions (CWOTIDIDTHAR?).</p>

<p><a href="http://darrennolan.com/wp-content/uploads/2010/09/recaptcha.png" rel="lightbox[698]"><img class="aligncenter size-full wp-image-699" title="recaptcha" src="http://darrennolan.com/wp-content/uploads/2010/09/recaptcha.png" alt="" width="250" height="155" /></a>It's actually really to get set up and working on your site, for anything really - not just contact forms (although it works quickly there too).  Basically you sign up for a Private and Public Key over at <a href="http://www.google.com/recaptcha">google</a> and then download the quick <a href="http://code.google.com/p/recaptcha/downloads/list?q=label:phplib-Latest">library</a> to use it.</p>

<p>After you've put it somewhere with your code files, you include the file, add some lines of code, and volia.  How easy is that.  See below;</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php
	require_once('recaptchalib.php');
	$privatekey = &quot;your_private_key&quot;; // Change this to your Private Key
	$publickey = &quot;your_public_key&quot;; // Change this to your Public Key
 
	if (isset($_POST['login'])) {
		// Do some validation stuffs here!
 
		// Check the Captcha
		$resp = recaptcha_check_answer ($privatekey,
		$_SERVER[&quot;REMOTE_ADDR&quot;],
		$_POST[&quot;recaptcha_challenge_field&quot;],
		$_POST[&quot;recaptcha_response_field&quot;]);
		if (!$resp-&gt;is_valid) {
			// reCaptcha failed. Do stuffs
 
		} else {
			// reCaptcha all good. Do whatever else
 
		}
	}
?&gt;&lt;html&gt;
&lt;head&gt;&lt;/head&gt;
&lt;body&gt;
	&lt;form method=&quot;POST&quot; action=&quot;&lt;?=$_SERVER['PHP_SELF'];?&gt;&quot;&gt;
		&lt;input type=&quot;text&quot; name=&quot;username&quot; /&gt; &lt;br /&gt;
		&lt;input type=&quot;password&quot; name=&quot;password&quot; /&gt; &lt;br /&gt;
		&lt;?=recaptcha_get_html($publickey);?&gt;
		&lt;input type=&quot;submit&quot; name=&quot;login&quot; /&gt;
	&lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>

<p>You can change the "look" or theme of reCaptcha by adding a small snippet of javascript before the element appears;</p>

<pre class="brush: jscript; title: ; notranslate">
&lt;script type=&quot;text/javascript&quot;&gt;
	var RecaptchaOptions = {
		theme : 'clean'
	};
&lt;/script&gt;
</pre>

<p>The element appears in a div with the ID of "recaptcha_widget_div" so if you want to adjust margins or padding for that div it appears in (being as lazy as me and NOT wanting to have more container divs than I can poke a stick at) you can change that in your own CSS stylesheets.</p>

<p>And that's about it for the moment. Hope I killed loads of your time and you wish for it back.  ^_^</p>]]></content:encoded>
			<wfw:commentRss>http://darrennolan.com/2010/09/03/email-contact-forms/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Using Redmine on a cPanel server &#8211; Silly .htaccess rules</title>
		<link>http://darrennolan.com/2010/05/23/using-redmine-on-a-cpanel-server-silly-htaccess-rules/</link>
		<comments>http://darrennolan.com/2010/05/23/using-redmine-on-a-cpanel-server-silly-htaccess-rules/#comments</comments>
		<pubDate>Sun, 23 May 2010 05:19:11 +0000</pubDate>
		<dc:creator>Dazz</dc:creator>
				<category><![CDATA[cPanel]]></category>
		<category><![CDATA[Redmine]]></category>
		<category><![CDATA[subdirectory]]></category>
		<category><![CDATA[subdomain]]></category>

		<guid isPermaLink="false">http://www.darrennolan.com/?p=83</guid>
		<description><![CDATA[It's not nearly has hard when you know what the hell you're doing.  Oh by the way, that's not the case with me &#60;_&#60;  Find an installation guide elsewhere (or even adapt the actual installation guide from Redmine).  This guide is manually how to setup rewrite rules properly so you can use Redmine as ether [...]]]></description>
			<content:encoded><![CDATA[<p>It's not nearly has hard when you know what the hell you're doing.  Oh by the way, that's not the case with me &lt;_&lt;  Find an installation guide elsewhere (or even adapt the actual installation guide from Redmine).  This guide is manually how to setup rewrite rules properly so you can use Redmine as ether a proper subdomain entry (redmine.yourdomain.com) or even slightly more tricky, as a subdomain entry (www.yourdomain.com/redmine).  Sadly cPanel htaccess rules generated from their interface ... suck.  Pretty badly &gt;_&gt;  No idea why.</p>

<p>MOVING ON.</p>

<p><span style="text-decoration: underline;"><strong>Bit 1</strong></span><br>
Go into cPanel -&gt; Ruby on Rails<br>
Create a new application by entering the application name.  Be happy with the default location it will store your application (/rails_apps/redmine for example)<br>
Ensure it's going to start when someone reboots the server on you (sif  they'd do that anyway).  Tick "Load on Boot".<br>
Don't bother starting the application yet.<br>
Find out which port you've been assigned - click "URL" and you should be taken to a page that can not be displayed - you'll see something like http://yourdomain:PORTNUMBER - the portnumber folks is important.<br>
</p>

<p><span style="text-decoration: underline;"><strong>Bit 2</strong></span><br>
Go into cPanel -&gt; MySQL databases<br>
Generate a new database, a new username/password and ensure you assign the new user to the database we just created.<br>
</p>

<p><span style="text-decoration: underline;"><strong>Bit 3</strong></span><br>
Get into shell or FTP (whatever is available to you) and remove everything that's pre-generated under ~/rails_apps/redmine<br>
Extract the latest redmine application source and put it in that folder we just cleaned out.<br>
Copy config/database.yml.example to config/database.yml<br>
Edit that file, change the stuff about production and what your MySQL details are (seek the real installation for more info - <a href="http://www.redmine.org/wiki/redmine/RedmineInstall">http://www.redmine.org/wiki/redmine/RedmineInstall</a>)Also following that installation guide, ensure you do the following parts<br>
Get into shell as your cpanel user and enter the following funky stuffs;
</p>
<pre class="brush: bash; title: ; notranslate">
cd ~/rails_app/redmine
RAILS_ENV=production rake config/initializers/session_store.rb
RAILS_ENV=production rake redmine:load_default_data
</pre>

<p><span style="text-decoration: underline;"><strong>Bit 4</strong></span><br>
In cPanel -&gt; Ruby Applications, you can go ahead and start the server now.</p>

<p>Now here comes the main part of this little installation guide (there are more completed installation guides out there on the web guys.</p>

<p><span style="text-decoration: underline;"><strong>THE IMPORTANT HTACCESS REWRITE BIT</strong></span></p>
<p>Wherever your "public" html access is, go there and create a .htaccess file.  For example if redmine is being put in your main domain's location, your location will be ~/public_html/.htacces - if it's a subdomain it's typically ~/public_html/subdomain/.htaccess unless you specified otherwise (which I always recomment... shoving subdomains under another domains document root is tacky, especially when dealing with .htaccess)</p>

<p>For "Whole" domain/subdomain (http://redmine.yourdomain.com) installations, put in the following text in the htaccess file</p>

<pre class="brush: plain; title: ; notranslate">
RewriteEngine on
RewriteCond %{HTTP_HOST} ^redmine.yourdomain.com$ [OR]
RewriteCond %{HTTP_HOST} ^www.redmine.yourdomain.com$
RewriteRule ^.*$ &quot;http\:\/\/127\.0\.0\.1\:12001%{REQUEST_URI}&quot; [P,QSA,L]
</pre>

<p>The two RewriteCond(itions) there are limiting this to the subdomain redmine.  If you aren't playing with a subdomain you can actually remove those two lines.
This htaccess example is "pretty much" what cPanel generates at time of writing, minus the "^.*$" part, for whatever reason they're still having ? inserted in there which naturally, causes headaches.</p>

<p>Now the uber tricky part.  You want it to be http://www.yourdomain.com/redmine - a "directory".<br>
First up - edit ~/rails_apps/redmine/config/environment.rb and at the very end of the file (even after the "end" part) add the following</p>
<pre class="brush: plain; title: ; notranslate">Redmine::Utils::relative_url_root = &quot;/redmine&quot;</pre>

<p>In your htaccess file, you'll want to do the following.</p>

<pre class="brush: plain; title: ; notranslate">
RewriteEngine On
RewriteRule ^redmine$ http://localhost:12002/$1 [P,QSA,L]
RewriteRule ^redmine/(.*)$ http://localhost:12002/$1 [P,QSA,L]
</pre>

<p>Again, ignoring the Rewrite conditions if you aren't setting up /redmine on a subdomain.</p>

<p>Notice where the 12001 part is in the htaccess files, you'll want to change that to whatever port number cPanel has set your redmine application to.</p>

<p>Edit: Updated htaccess rule for the subdirectory.  It appears that despite my efforts redmine would only work if there was a trailing slash.  Without it, it wasn't working.  Then I got it working the other way around....  and now... I have two rules... not ideal but it's working again.  \o/</p>]]></content:encoded>
			<wfw:commentRss>http://darrennolan.com/2010/05/23/using-redmine-on-a-cpanel-server-silly-htaccess-rules/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Getting back to development</title>
		<link>http://darrennolan.com/2010/05/08/getting-back-to-development/</link>
		<comments>http://darrennolan.com/2010/05/08/getting-back-to-development/#comments</comments>
		<pubDate>Sat, 08 May 2010 02:58:59 +0000</pubDate>
		<dc:creator>Dazz</dc:creator>
				<category><![CDATA[Editors]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Dark Scheme]]></category>
		<category><![CDATA[Dark Theme]]></category>
		<category><![CDATA[Monaco]]></category>
		<category><![CDATA[Notepad++]]></category>
		<category><![CDATA[VibrantInk]]></category>

		<guid isPermaLink="false">http://www.darrennolan.com/?p=75</guid>
		<description><![CDATA[And it starts with Notepad++, because it&#8217;s lightweight, awesome, sexy, and did I mention awesome.  I am a bit of a fan of Textmate on the Mac &#8211; using a combination of the font Monaco (which you&#8217;ll need to source for yourself) and the VibrantInk theme created by Tyler at impoverishedgourmet.com &#8211; you too can [...]]]></description>
			<content:encoded><![CDATA[<p>And it starts with Notepad++, because it&#8217;s lightweight, awesome, sexy, and did I mention awesome.  I am a bit of a fan of Textmate on the Mac &#8211; using a combination of the font Monaco (which you&#8217;ll need to source for yourself) and the VibrantInk theme created by Tyler at impoverishedgourmet.com &#8211; you too can have a nice dark scheme for your coding box.</p>
<p>Next up will be finding a similar solution for Netbeans.</p>
<p>In order to install this theme, simply go place the file into %APPDATA%\Notepad++ replacing the existing theme (I like to make backups of this shit in case I ever start to hate the contrast).</p>
<p><a href="http://darrennolan.com/wp-content/uploads/2010/05/notepad++.png" rel="lightbox[75]"><img class="aligncenter size-medium wp-image-76" title="notepad++" src="http://darrennolan.com/wp-content/uploads/2010/05/notepad++-300x207.png" alt="" width="300" height="207" /></a></p>
<p><a href="http://darrennolan.com/wp-content/uploads/2010/05/stylers.xml">http://www.darrennolan.com/wp-content/uploads/2010/05/stykers.xml</a></p>
<p>Font is then changed in Notepad++ by going to Settings -&gt; Style Configurator, ensure you have Global Styles (Global override) selected, and change the font to Monaco.</p>
]]></content:encoded>
			<wfw:commentRss>http://darrennolan.com/2010/05/08/getting-back-to-development/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

