A Smarty Solution

Last month, we looked into Smarty (http://smarty.php.net), a powerful templating system for PHP. To recap, Smarty provides a separation of program logic from web site design. Your code does whatever it needs to do to fetch, process, and store data, and when you need to display something, you instantiate Smarty and ask it to render a particular template, passing in any necessary data. Smarty templates are written in a simple markup language that looks a bit like a cross between XML and PHP.

Last month, we looked into Smarty (http://smarty.php.net), a powerful templating system for PHP. To recap, Smarty provides a separation of program logic from web site design. Your code does whatever it needs to do to fetch, process, and store data, and when you need to display something, you instantiate Smarty and ask it to render a particular template, passing in any necessary data. Smarty templates are written in a simple markup language that looks a bit like a cross between XML and PHP.

Several readers asked to see Smarty in a more concrete, simple example. So, this month, we’ll look at a very simple PHP/MySQL/Smarty application that might be useful to pilots.

Logging

Like programmers, pilots have to worry about logs. The Federal Aviation Administration (FAA) requires all pilots to keep a minimal log, both on the aircraft flown, and on their own flight experience.

Each aircraft a pilot flies may have a log book associated with it. If a plane has a log, each pilot is expected to log her name, the date, the duration and number of flight(s), and any problems encountered with the aircraft along the way. Aircraft owners like it when pilots do their part to keep the records up to date.

Each pilot also logs his flights in a personal log book. The required information is very basic: the date, flight number, aircraft type, flight duration, location of the flight, remarks, and how the flight time was spent: solo, PIC (pilot-in-command), dual instruction time (flying with an instructor), or instruction given (flying as an instructor).

Now, the funny thing is that while the aviation community is relatively technical, its logs are decidedly low-tech. Many pilots use GPS devices, computer-based flight planning and weather services, and even hand-held computers, but virtually all pilots still use paper log books to record flight info.

Perhaps simple minded in this day and age, the logs, in fact, serve a very valuable purpose: a pilot may occasionally have to answer various questions about their flight experience. Many flying clubs, for example, place restrictions on pilots to make sure they have sufficient experience before trying something new. Common questions include:

Have you flown at least three takeoffs and landings it the last ninety days?

How many times have you flown this model aircraft in the last twelve months?

Do you have at least three flights which lasted more than three hours?

The questions vary, but they’re virtually all simple counting and filtering problems — the kinds of problems that are very easy to answer with a database query or two.

A Smarty Solution

To solve this problem, let’s build a one-page log book summary in PHP. The data will come from a logbook table in MySQL that’s specifically designed for logging glider flights. Listing One contains the CREATE TABLE definition for logbook.




Listing One: A table to log glider flight data

CREATE TABLE ‘logbook’ (
‘flight_num’ mediumint(8) unsigned NOT NULL default ’0′,
‘flight_date’ date NOT NULL default ’0000-00-00′,
‘craft_model’ char(12) NOT NULL default ”,
‘craft_num’ char(8) NOT NULL default ”,
‘tow_type’ enum(‘Aero’,'Auto’,'Winch’,'Self’) NOT NULL default ‘Aero’,
‘craft_frame’ enum(‘Wood’,'Metal’,'Glass’) NOT NULL default ‘Wood’,
‘flight_release_alt’ mediumint(8) unsigned NOT NULL default ’0′,
‘flight_max_alt’ mediumint(8) unsigned NOT NULL default ’0′,
‘takeoff_loc’ char(3) NOT NULL default ”,
‘landing_loc’ char(3) NOT NULL default ”,
‘time_dual’ decimal(5,2) NOT NULL default ’0.00′,
‘time_pic’ decimal(5,2) NOT NULL default ’0.00′,
‘time_solo’ decimal(5,2) NOT NULL default ’0.00′,
UNIQUE KEY ‘flight_num’ (‘flight_num’)
) TYPE=MyISAM

The table collects interesting tidbits, such as the aircraft frame type. This is handy when you need to compute the amount of time (or number of flights) in a fiberglass craft versus those constructed from metal or wood.

Assuming that the table’s been populated with accurate data (we don’t have the space to build a data entry page for it here), let’s build PHP code to query the table and compute various interesting statistics. Once the data’s been extracted, we’ll send it off to Smarty to render an HTML page.

Listing Two contains the PHP and SQL code needed to gather the data. Now, this isn’t the best model of PHP programming. We’re sacrificing a bit in the design department to focus on building a simple but real-world Smarty application. You’d probably want to use subroutines (or object methods) to encapsulate the various queries that extract information from the database.




Listing Two: summary.php, PHP code to collect and compute flight data

<?php

// connect
$db_conn = mysql_connect(“localhost”, “jzawodn”,
“Pfal44″);
mysql_select_db(“flying”, $db_conn);

// total flights in various types
$sql = “select count(*) as cnt, craft_frame from
logbook group by craft_frame”;
$rs = mysql_query($sql, $db_conn);
$frame_flights = array();

while ($obj = mysql_fetch_object($rs))
{
array_push($frame_flights, $obj);
}

// get 10 most recent flights
$sql = “select * from logbook order by flight_num desc limit 10″;
$rs = mysql_query($sql, $db_conn);
$ten_recent = array();

while ($obj = mysql_fetch_object($rs))
{
array_push($ten_recent, $obj);
}

// total PIC time and flights
$sql = “select sum(time_pic) as pic_time from
logbook”;
$rs = mysql_query($sql, $db_conn);
$obj = mysql_fetch_object($rs);
$pic_time = $obj->pic_time;

$sql = “select count(*) as pic_flights from
logbook where time_pic > 0″;
$rs = mysql_query($sql, $db_conn);
$obj = mysql_fetch_object($rs);
$pic_flights = $obj->pic_flights;

mysql_close($db_conn);

// Smarty stuff
require(‘Smarty.class.php’);

$smarty = new Smarty;

$smarty->assign(‘frame_flights’, $frame_flights);
$smarty->assign(‘ten_recent’, $ten_recent);
$smarty->assign(‘pic_time’, $pic_time);
$smarty->assign(‘pic_flights’, $pic_flights);
$smarty->display(‘summary.tpl’);

?>

The technique used to handle the lists of record is typical: the code loops through each record using one of the mysql_ fetch_* functions (mysql_fetch_object(), in this case) and pushes the data onto an array. Later on, that array is simply assigned to a variable in the Smarty template.








lamp_01
Figure One: The log book summary page

With all the data collected, Smarty can evaluate the template to produce the HTML. Listing Three (pg. 52) contains the template, and Figure One contains a screenshot of the result. The template starts off with some basic HTML. Smarty’s built-in now method gets the current date, which is then passed through a the date_format filter to get the format we want. Smarty’s foreach construct loops over an array that contains objects returned from MySQL. The template doesn’t care where the data came from: it could have been derived from flat files or an XML document.




Listing Three: A Smarty template

<html> <head> <title>Logbook Summary</title> </head> <body>
<h1>Logbook Summary</h1>
<p>As of {$smarty.now|date_format:”%m-%d-%Y”} (today)
you have accumulated the following number of flights
in these craft type:</p>

<table border=”1″ cellspacing=”0″ cellpadding=”4″>
{foreach from=$frame_flights item=flight_info}
<tr>
<td>{$flight_info->craft_frame}</td>
<td>{$flight_info->cnt}</td>
</tr>
{/foreach}
</table>

<p>You’ve logged {$pic_time} hours as Pilot-in-Command during
{$pic_flights} flights.</p>

<h2>Ten Most Recent Flights</h2>
<table border=”1″ cellspacing=”0″ cellpadding=”4″>
{foreach from=$ten_recent item=flight}
<tr>
<td>{$flight->flight_num}</td>
<td>{$flight->flight_date}</td>
<td>{$flight->craft_frame}</td>
<td>{$flight->craft_num} ({$flight->craft_model})</td>
</tr>
{/foreach}
</table>
</body> </html>

Next, the template uses a couple, simple in-line variables to display accumulated pilot-in-command flights and time. Finally, we loop through the ten most recent flights to produce a table that lists some basic data about each flight.

Clean. Simple. Smart.

You might notice the complete lack of any “real” PHP code or tags in the Smarty template. There are no <?php> and no <?> tags, and no function calls. The only things reminiscent of PHP code are the dollar signs and the arrow (->) syntax used to access object values. You could hand this template to a designer without having to worry about her software re-writing its “logic.” Your designer can make all sorts of visual changes (color, font faces and sizes, and layout) without ever once touching your PHP code.

And since there’s an explicit layer between the template and the back-end code, you could completely re-work the way summary.php works and never touch the template. As long as you $smarty->assign() the expected variable names, the templates will continue to function as expected.

The separation of form and function provided by Smarty is essential on larger projects. But even on a simple, single-developer project (like this one), Smarty still provides an important advantage: your code looks less cluttered. It can focus on the task at hand without ever worrying about how to display the data.



Jeremy Zawodny plays with MySQL by day and spends his spare time flying gliders in California and writing a MySQL book for O’Reilly & Associates. You can reach him at: jeremy@zawodny.com.

Fatal error: Call to undefined function aa_author_bios() in /opt/apache/dms/b2b/linux-mag.com/site/www/htdocs/wp-content/themes/linuxmag/single.php on line 62