Mozilla Add-ons you can't live without.

As a PHP developer there are a hoard of Mozilla Firefox add-ons that will not only make your life easier, but will make you a better developer.

These are the list of add-ons that are installed by default in my Firefox Browser.

Firebug – absolutely the best way to debug javascript (and therefore also ajax) in your web projects. console.log beats using alert() anyday.

Web Developer – the first developer add-on I ever installed and one that I can’t live without. Manipulate everything from styling to sessions using this tool.

Tamper Data – extremely useful tool for viewing/modifying your http requests to see what is being sent/received each time a page is loaded.

PHP Developer Toolbar – tired of opening php.net each time you want to search a function. Use this handy toolbar to save time and frustration.

Filed under: DevelopmentTagged with: , ,

Easy CakePHP in Ubuntu

I’ve always setup a new CakePHP project by extracting the current stable build into a project directory and editing the core.php and database.php files manually. I usually then change to the /cake/console directory of the project and run php cake.php bake (having already installed the php-cli) to bake my code.

I know there are other ways to make this process simpler but its always just worked for me and I am usually to lazy/busy/unmotivated to try something new.

Today, however, I stumbled across a great way to set up CakePHP in Ubuntu so that building new projects is a simple matter of running one line from the command line and you are ensured of using the same stable “shell” version of Cake each time. It is also extremely easy to upgrade your “shell” version whenever you want. (It also makes baking even easier than the way I was doing it but that’s just an added bonus !)

(This may or may not also be possible in other Ubuntu like systems that have the same CakePHP repositories eg Mint, Debian etc)

1) Download and extract the latest stable version of CakePHP to a folder on your machine.

2) Install cakephp-scripts from the Ubuntu repositories

$ sudo apt-get install cakephp-scripts

This will install the current version of CakePHP in the Ubuntu repository, as well as the php-cli (command line interface) and setup the Cake console for easy use from the command line.

3) Copy the folders from the latest stable version to your system

Currently you have installed whatever version of cake was included in your version of Ubuntu’s repositories. If you are running an older version of Ubuntu or just want to run the very latest stable version, you need to update your Cake version by copying it from the extracted folder in step 1.

The “shell” version of CakePHP you installed in step 2 is located in /usr/share/php/cake. You will notice that the directory structure is slightly different from the extracted version, but a little common sense will enable you to see what needs to be copied to where (basically, from the extracted directory, copy the app directory and everything from inside the cake directory into the /usr/share/php/cake directory).

You can also upgrade your “shell” by downloading/extracting a newer stable version of CakePHP and repeating the above step.

Now baking with Cake becomes even easier.

Change to your web root (usually /var/www/ or wherever you usually develop your PHP applications) and run

$ cake bake projectname

where projectname is the name of a new project you want to create. You will be presented with the Cake console, which will set up your project folder and copy over all the code from the CakePHP “shell”. It will also set up a random Security Salt value, add some default CAKE_CORE_INCLUDE_PATHs and guide you through setting up your database configuration(s).

You can then change directory to your projectname directory and run

$ cake bake

to bake your Models, Views and Controllers.

Happy Baking…

UPDATE: I just noticed another nice side effect of this way of creating Cake projects, default app_controller.php, app_helper.php and app_model.php files are created in the project root folder. 😉

Filed under: DevelopmentTagged with: , , ,

Ambit Recruitment website goes live

Personal experience will always advise our actions. So, the objective is to ensure positive experiences are repeated as often as possible, to encourage further positive outcomes.

That’s the simple premise on which Ambit Recruitment operates the business of fitting the right people into the right positions.

The Ambit Recruitment website is a bit of a milestone for me, as it is the first site that I handcoded from scratch (HTML/CSS/PHP). I am quite proud of how it turned out.

Filed under: DevelopmentTagged with:

South African HTML image map

I recently had to create an image map of South Africa, displaying each of the provinces with links to content for each province.

As it took me most of the day to complete I thought it might be handy for someone else too.

So in true open source fashion here it is for you to download and enjoy.

All I ask is that if you do use it, you post a link back to my site.

Filed under: DevelopmentTagged with: , , ,

Migrating from Drupal to WordPress

Well, it finally happened. After months of frustration with Drupal as a blog tool, I gave up and decided it was time to move over to WordPress.

I’m sure as a CMS system Drupal can be quite wonderful, but for running and managing a simple blog site, I have yet to come across a better platform than WordPress.

However the migration of the database content from one system to another had it’s ups and downs. Fortunately for me, not many people read this blog, so I only had to migrate the posts data from one database to the other.

Below is the script I wrote to do so, in the hopes that this might save someone else the hassle of writing it themselves.

P.S. This was for a Drupal 6 to WordPress 2.8.2 migration. If it doesn’t work for you because you are working with different versions of either Drupal or WordPress, drop me a line and I will try to modify it for you.


	/**
	* Setup database constants
	*/
	define('DRUPAL', 'phpdevec_drpl1');
	define('WORDPRESS', 'phpdevec_wordpress');
	define('URL', 'http://www.php-developer.co.za/');
	/**
	* Setup server constants
	*/
	define("SERVER", "localhost");
	define('USER', 'username');
	define('PASSWORD', 'password');

	/**
	* debug function outputs data
	*/
	function debug($data){
		echo '<pre>';
		print_r($data);
		echo '</pre>';
	}

	/**
	* Connect to server and database
	*/
	function connect($db) {
		// database connection
		$conn = mysql_connect(SERVER, USER, PASSWORD);
		if (!$conn) {
			//connection to server failed
			die("Cannot connect to server");
			return false;
		}

		$dbSelected = mysql_select_db($db, $conn);
		if(!$dbSelected) {
			// database connection failed
			die("Cannot connect to database");
			return false;
		}
		return $conn;
	}

	/**
	* Close database connection
	*/
	function disconnect($conn){
		if ($conn){
			// connection exists to close
			if (!mysql_close($conn)){
				// database connection failed
				die("Cannot close database connection");
				return false;
			}
			return true;
		}
		// default return in case the original connection failed
		return true;
	}

	/**
	* Generic SQL SELECT, checks type
	* (SELECT, INSERT, UPDATE [DELETE])
	*
	* @param string $sql query
	* @param string $type object or assoc
	* @return mixed $return array of rows if select or true/false if insert/update/delete
	*/

	function sql($sql, $database, $type = 'assoc'){
		$return = '';

		// check database connection
		$connection = connect($database);
		if (!$connection){
			$return = false;
		}

		$sql = ltrim($sql);
		$query_type = substr($sql, 0, 6);

		// run query
		$rst = mysql_query($sql);

		if (!$rst){
			// query failed for some reason
			die("Error in MySQL query: " . $sql);
			$return = false;
		}else {

			if (strtoupper($query_type) == "SELECT"){
				// query was SELECT
				$return = array();
				$rows = mysql_num_rows($rst);

				switch($type) {
					case 'assoc' : // return as assoc array
						while($row = mysql_fetch_array($rst)) {
							// gather rows
							$return[] = $row;
						}
						break;
					default : //return as object
					while($row = mysql_fetch_object($rst)) {
						// gather rows
						$return[] = $row;
					}
				}
			}else {
				// query was INSERT, UPDATE OR DELETE
				$queryType = 'UPDATE';
				if (mysql_insert_id()){
					// query was INSERT
					$id = mysql_insert_id();
					$queryType = 'INSERT';
					$return = $id;
				}else {
					$rows = mysql_affected_rows();
					$return = $rows;
				}
			}
		}

		// disconnect from database
		disconnect($connection);

		//return rows / whether insert/update/delete successful
		return $return;
	}

	$sql = "SELECT n.*, nv.body as content FROM node as n LEFT JOIN node_revisions as nv on n.nid = nv.nid WHERE n.type = 'blog'";

	$nodes = sql($sql, DRUPAL);

	//debug($nodes);

	$Nodes = array();

	foreach ($nodes as $node){
		$nId = $node['nid'];
		$sql = "SELECT * FROM comments WHERE nid = '$nId'";
		$comments = sql($sql, DRUPAL);
		$node['comments'] = $comments;
		$Nodes[] = $node;
	}

	//debug($Nodes);

	foreach ($Nodes as $node){
		//publish draft

		$two_hours = 2*3600;
		$date = $node['created'];
		$gmt_date = $date - $two_hours;
		$modified = $node['changed'];
		$gmt_modified = $modified - $two_hours;

		$post_date = date('Y-m-d H:i:s', $date);
		$post_date_gmt = date('Y-m-d H:i:s', $gmt_date);
		$post_modified = date('Y-m-d H:i:s', $modified);
		$post_modified_gmt = date('Y-m-d H:i:s', $gmt_modified);

		$post_title = mysql_escape_string($node['title']);
		$post_content = mysql_escape_string($node['content']);
		$post_name = strtolower(str_replace(array(' ', '.'), array('-', ''), $post_title));

		$status = $node['status'] == '1' ? 'publish' : 'draft';

		$sql = "INSERT INTO phpdevec_posts SET
			post_author = 1,
			post_date = '$post_date',
			post_date_gmt = '$post_date_gmt',
			post_content = '$post_content',
			post_title = '$post_title',
			post_status = '$status',
			comment_status = 'open',
			ping_status = 'open',
			post_name = '$post_name',
			post_modified = '$post_modified',
			post_modified_gmt = '$post_modified_gmt',
			post_parent = '0',
			menu_order = '0',
			post_type = 'post',
			comment_count = 0";

		$id = sql($sql, WORDPRESS);

		if (!$id){
			die('An error occured adding the data to the database');

		}

		/*
		if (!empty($comments)){
			foreach ($comments as $comment){
			}
		}
		*/

		$guid = URL . "?p=$id";

		$sql = "UPDATE phpdevec_posts SET guid = '$guid' WHERE ID = '$id'";

		$updated_rows = sql($sql, WORDPRESS);

		if (!$updated_rows){
			die('An error occured updating record no '. $id);
		}
	}

Filed under: DevelopmentTagged with: , ,

Riding on Rails

I’ve decided to spend less of my free time on blogging and more on learning new things. I had planned to change this site to run on WordPress, but have decided instead to learn Ruby on Rails.

From what I can see it is (in many ways) similar to CakePHP (which I love) but with more of a command line/linux approach. Also it’s a new and interesting language to learn, so I’m sure there will be some exciting challenges along the way.

I don’t know where this new road will take me, but if its anything like CakePHP, I’m sure it will be fun. (yes, only geeks find coding fun!)

In other (u)interesting news, the FCK Editor helper I wrote has been used as part of someone else’s cake-bake-enhanced project.

To be honest I think it’s kinda cool, my first CakePHP helper and people are actually finding it worthwhile…time to write some more…

Filed under: Development

Developing with CakePHP: Creating a simple admin control panel

If you are like me, you prefer to have a specific url mapped to your applications control panel/backend etc.
This is usually something along the lines of www.url.com/admin or www.url.com/cms.

Normally during the CakePHP “bake” process, the system will ask you what you want your admin route to be (default “admin”). Once this has been set you are merely 3 simple steps away from creating your own simple user control panel….

Step 1) Routing the admin url.
Add the following to your app/config/routes.php

Router::connect(‘/admin/’, array(‘controller’ => ‘admin’, ‘action’ => ‘index’));

This will route url.com/admin to the admin controller index function

Step 2) Creating the admin controller
Create the admin_controller.php file in /app/controllers/ and add the following code

class AdminController extends AppController
{
var $name = ‘Admin’;
var $uses = array(); //This controller does not need to use a model

function index(){

}
}

Step 3) Create your views
Create the app/views/admin/ directory and add an index.ctp view to it, with whaterver code you prefer (mine is merely a bunch of links to other controllers at this stage)

  • link(‘Posts’, ‘posts/’);
  • link(‘Comments’, ‘comments/’);
Filed under: DevelopmentTagged with: ,

Create an array containing the days of the week

You could simply code:

$days_of_week = array(‘Monday’, ‘Tuesday’, ‘Wednesday’, ‘Thursday’, ‘Friday’, ‘Saturday’, ‘Sunday’);

but thats the “noob” way, a real coder creates a function…

function days_of_week(){
// declare days_of_week array
$days_of_week = array();

// get current date integer value (0 – 6)
$day = date(“w”);

// get current date values
$today = date(“j”);
$month = date(“n”);
$year = date(“Y”);

// get start day and end day of the week
$start_day = $today – $day;
$end_day = $start_day + 6;

// build days of the week array
for ($i = $start_day; $i <= $end_day; $i++) {
$days_of_week[] = date(“l”, mktime(0,0,1,$month,$i,$year));
}

// return array
return $days_of_week;
}

Filed under: DevelopmentTagged with: , ,

PHP.js

This is something I came across a while ago, but it has really come in handy.

It is a project that attempts to make many php functions available in javascript. As most php developers will at some point have to write some javascript, it is a very handy library.

You can find it over at http://www.ohloh.net/p/php-js.

Filed under: DevelopmentTagged with: , ,