Thursday, August 04, 2005

theFalls

coming soon...

www.the-falls.net

osCommerce

Tony was in the other day and got me thinking about setting up online catalogs and purchasing. He was given a ridiculously low quote - the secret of which I think I've sourced...

We'll be testing it out on a small scale site today, as a proof of concept, and then hopefully think about how we're going to offer this to our clients.

osCommerce, Open Source Online Shop E-Commerce Solutions

Fan-f^#n-tastic

Tuesday, July 05, 2005

The damn flu keeps coming back, I'll be fine and go into work one day and the next my head's splitting, arms are aching and my head's thicker than a crusty Italian loaf. Either way, andiamo...

I've wrapped up most of the big jobs for work, with Multiplex being the final one out the door. This means I finally have time to do our site, and Ben's bands site, which is a good thing. But they're both very fiddly jobs - the former because it's the table-soup that I used to call "web design", and the second because it just involves ripping apart Photoshop mockups, placing them into Flash and "rocking them up". Unfortunately "rocking up" is frequently interrupted by cups of tea and tissues at the moment...

I mention table-soup due to my fairly recent conversion to CSS/XHTML and JavaScript/DOM/XmlHttpRequest, three bits of technology that I'm overawed with lately. But this is an update, and my drooling over the wonders of the dynamic web should be saved until I'm fully ready to do them justice.

I've also applied for a credit card - and been knocked back, despite my thick wad of invoices. If anyone is a contractor, or gets paid by invoices, and has any suggestions for how to acquire a credit card, I'd love to hear them. Otherwise, I might try and get a debit card. Chris and Pat?

I'm also toying on a couple of new web fronts. Some things that have really quite excited me, but I'll see how they turn out over the next month or so before I get too carried away.

And finally - gotta make this blog look good, IE *ergh*.

Sunday, June 26, 2005

DB_DataObject_FormBuilder :: A Simple Tutorial

DB_DataObject_FormBuilder is a great Pear package for quickly prototyping database interaction. Unfortunately, there's a lack of documentation on how to use it, especially with regards to actually building something in practice. I recently had to build that timeless web classic, a "News Admin" system for a client... on the morning before a meeting at 11am. Although I'm in the process of rewriting the system in full, FormBuilder made prototyping the system extremely quick, so that it was done for my demonstration and I could get feedback on anything they wanted changed (thankfully, nothing).

This will be a tutorial on creating a simple news posting system, using DB_DataObject_FormBuilder.

The DataLayer

The first thing we need to do is model the data, and create our data source. This is going to be a fairly simple system - allowing users to enter a title and a body for the news (and store the date), and edit and delete that news.

So with that simple set of requirements, we'll create a database table, something like:

CREATE DATABASE news;

GRANT ALL PRIVILEGES ON news.*
TO 'news_usr'@'localhost'
IDENTIFIED BY 'news_usr';

USE news;

CREATE TABLE post (
id INT NOT NULL AUTO_INCREMENT,
time DATETIME,
title VARCHAR( 255 ) NOT NULL,
body LONGTEXT NOT NULL,
PRIMARY KEY( id )
);


On we go, and the first thing we want to do is generate the DataObject class that will interact with the post database table, so we create db_dataobject.ini like so:

[DB_DataObject]

database = mysql://root@localhost/news
schema_location = /Users/mike/Sites/news/config/
class_location = /Users/mike/Sites/news
extends = DB_DataObject
extends_location = DB/DataObject.php


I'm using accessing the database as root, which of course you wouldn't do in a production environment. I've also split the configuration files into a subdirectory of my main news directory.

Now we just run

php createTables.php /Users/mike/Sites/news/config/db_dataobject.ini

from within the DB/DataObject directory to create the class (Post.php).

At this point it's probably worth illustrating my directory structure, so that makes more sense.

/Users/mike/Sites/news/
/Users/mike/Sites/news/config/
/Users/mike/Sites/news/lib/
/Users/mike/Sites/news/lib/DB/
/Users/mike/Sites/news/lib/PEAR/
/Users/mike/Sites/news/lib/...


Accessing the DataLayer

We haven't seen any FormBuilder code, but it's close. Seeing as this is a fairly simple example, I've created /Users/mike/Sites/news/config/post.config.php. This sets up DataObjects and can easily be included whenever you need access to the Post class for database interaction.

<?php

define( "POST_FILE_ROOT", "/Users/Obz/Sites/news/" );
// Setup the PEAR includes
ini_set( "include_path", POST_FILE_ROOT . "lib/" );

// This version of PHP doesn't support overloading
define( "DB_DATAOBJECT_NO_OVERLOAD", TRUE );

require_once( POST_FILE_ROOT . 'Post.php' );
// Parse the DO config file
$config = parse_ini_file( POST_FILE_ROOT . 'config/db_dataobject.ini', TRUE );
foreach( $config as $class => $values ) {
$options = &PEAR::getStaticProperty( $class, 'options' );
$options = $values;
}

?>


Creating the interface

So, now we've created our DataLayer and made it easily accessible, we want to actually see something.

Create index.php, open a table and then try something like:

<?php

// Grab all of the posts
$post = new Post( );
$post->orderBy( 'time DESC' );
$post->find( );

// Loop over the results
while( $post->fetch( ) ) {
$p = clone( $post );

?>

<tr>
<td>

print( substr( $p->title, 0, 40 ) );
if( strlen( $p->title ) > 39 ) { print( "..." ); }
?>

</td>
<td><?= $p->time ?></td>
<td><a href="post_edit.form.php?id=<?= $p->id ?>">Edit this post</a></td>
<td><a href="post_delete.php?id=<?= $p->id ?>">Delete this post</a></td>
</tr>

<?php } ?>


Here we grab all of the Posts and order them by time, so that the newest posts are displayed first. We query the database, and loop over the result set printing out four columns of data.

First, there's a rather convoluted way of limiting the title to 40 characters, and appending "..." to indicate titles longer than 40 characters. Then we simply print out the time, and create two links to the forms for editing and deleting posts, which we'll create later.

Adding a new post

Okay, so we finally get to the FormBuilder part of this "FormBuilder" tutorial, but as I said earlier, this is supposed to be a real world prototype.

post_new.form.php looks something like:

<?php

require_once( 'config/post.config.php' );
require_once( 'DB/DataObject/FormBuilder.php' );

// Create a new, blank post
$post = new Post( );

// Create a FormBuilder for the post
$formBuilder = &DB_DataObject_FormBuilder::create( $post );

// Set up the form
$formBuilder->fieldAttributes = array( 'title' => array( 'class' => 'post_title' ),
'body' => array( 'class' => 'post_body' ) );

// Actually fetch the Form
$form = &$formBuilder->getForm( );

// If we validate, then we process it here
if( $form->validate( ) ) {
$form->process( array( &$formBuilder, 'processForm' ), false );
// Redirect
header( "Location: http://" . $_SERVER[ 'HTTP_HOST' ] .
dirname( $_SERVER[ 'PHP_SELF' ] ) . "/index.php" );
}

$form->display( );

?>


So let's walk through this.

First we include the required files, our configuration and the DB_DataObject_FormBuilder class. Next, we create a new blank DataObject post. The FormBuilder will use this object as a template for creating our form, so we can create the FormBuilder object.

As you can see, $formBuilder->fieldAttributes takes an array of associative arrays, the keys of which correspond to the field names, which in turn are determined by the properties of the DataObject, which are generated from the SQL. Confused? basically, it means that you just need to use the same name to refer to the property the whole way through the stack, eg 'title'.

If we validate, then we process the form and redirect. You can customize your validatation commands, but the default basically does no validation other than checking "did we just get a post?". We redirect back to the index after processing the form.

If we didn't validate, then we call $form->display( ); which prints (not returns) the HTML to create our form.

Of course, to redirect using header, we need to be processed before any headers are sent, which is why you might lump this code at the top of your page, output any HTML you need (a header for example), and then call $form->display( ); further down in the page body.

Simple?

Editing a post

To complete this tutorial, we'll create a form for editing a post. We've allready set the links up for this in our index.php, which simply pass the id of the post to post_edit.form.php.

The contents of post_edit.form.php are identical to post_new.form.php, except for one small change.

After creating the post with

$post = new Post( );

We set the id to be the id of the post we're editing

$post->get( $_REQUEST[ 'id' ] );

and then continue as normal. The FormBuilder will fetch the post from the database, and populate the fields with it's values.

Conclusion

Hopefully that's a bit of an introduction to FormBuilder and quickly prototyping your code. There's very little actual PHP coding to do with something quick like this, as it's mostly abstracted to the libraries.

Pear :: DB_DataObject
Pear :: DB_DataObject_FormBuilder
(Okay, so i just managed to check off "Ta-da lists" from my list of "Things to blog about.")

I like lists.

So I've had about a week to play with my Ta-da list. Unfortunately my 'list growth-to-tick off' ratio is blowing out, as I've failed to check off any of my things to do. However, I've definitely did do things this week, but they appear to be absent from my list. Why?

My theory on this pattern is that it seems my 'things to do' fall into two categories. First, there are the 'things I'm doing right now, or are due tomorrow, or are really big things to do'. These are generally uppermost in my mind, and taunting me when I sleep. The other group would be 'oh, remember to do this when you can sort of things'. For obvious reasons, these are less important than Group A, and are therefore more likely to be forgotten.

As you can probably guess by now, by Ta-da lists seem to be mostly filled with 'things to remember to do when you can', rather than 'get this done now!' things.

And if I haven't got to any of my 'try and do this when you can' items? I've been way too busy.

Wednesday, June 22, 2005

Hey presto.

For a while now I've tried several different ways to keep Todo lists. Stickies are just too heavy weight, but using the Dashboard version is too awkward for frequent reference.

After my recent switch to Thunderbird/Firefox (from Mail/Safari) I though I'd keep the Mozilla spirit going and try Sunbird. Unfortunately it's in a pretty alpha state and was prone to sporadic crashes, so next on the list was iCal.

I'd avoided moving to iCal because it irked me once when I found I couldn't drag and drop an email from Mail. I guess that's something you don't notice, moving from Linux full time to OS X full time. You just start to expect drag and drop integration between any applications, and for the simplest things to work.

iCal still wasn't quite right. See, I have very view real "appointments" and lots of things to "just get the hell done". I don't know what I'll be doing at 12pm on Thursday, but I do know I'll be working on the next thing on my... list. And so I decided I just needed a simple Todo list, no fancy organisation, planning and scheduling. Just a list of what needs to be done, so I can get on and start ticking things off.

I like lists.

So despite wishing for Tomboy I thought I'd try a web-based solution to the problem. Heck, all the rest of my activities are being replaced, so why not one more.

And so I chose Ta-da Lists, which seem to be a popular choice. I'll have to investigate the possibilities of Firefox/Thunderbird integration, having my Ta-da lists available in TB would just be too good.


Monday, June 20, 2005

Mozilla Update :: Extensions -- More Info:Sage - All Releases

Sunday, June 19, 2005

Doves


Doves
Originally uploaded by driver_red.

Weather report

I'm sure Nat would know the details, but the cool continues. Except it's not so much a cool as "freezing cold". We're not usually exposed to this sort of prolonged cold, especially since the last few winters have been fairly mild, and here in Perth we're more accustomed to 20oc + winter days as "cold".

It's actually quite lucky; the cold is one of my favourite things. And if nothing else, it's a slight acclimatisation for Europe, at the end of the year. Although with regards to that I keep thinking "you aint seen nothing yet...".

So yes, it's been a funny year for weather.

Saturday, June 18, 2005

Leederville


Leederville
Originally uploaded by driver_red.
Nat, coffee and Leederville in the cold.

Laying out in CSS

I've converted the default "Simple" layout to the custom CSS layout I recently implemented on my LiveJournal. I put it off for an hour or two, but in the end it only took me 15 minutes. Thanks, in part due to the page layout for Blogger being much easier to modify than the LiveJournal templates. The inline CSS is also laid out in a sensible fashion and well commented. Could I ask for more?

nat


nat
Originally uploaded by driver_red.
nat

Temp-ted.

The simple template looks like it might be the easiest to alter. I'll be working on porting over the CSS layout I had on my livejournal, and perhaps looking at the remaining IE issues I was having with that.

Also waiting on a Mail-to-Blogger post send from my mobile...

Going mobile...

PXT Message: Unfortunately posting via mobile only works for US customers, which is fair enough. Also unfortunately the alternative Mail-to-Blogger doesn't support image attachments. Maybe some sort of Flickr interaction is possible...

hello

... they all start like this.