I don't know of one in PHP. Here's a demonstration of one algorithm for creating the display, using a MySQL backend:
Given a table named "personnel" of the following structure, where the column "reports_to" contains the id of that person's immediate boss. The highest person in the company has a "reports_to" of 0.
[tt]+------------+-----------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-----------------+------+-----+---------+----------------+
| id | int(3) unsigned | | PRI | NULL | auto_increment |
| name_first | varchar(25) | | | | |
| name_last | varchar(25) | | | | |
| role | varchar(25) | | | | |
| reports_to | int(3) unsigned | | | 0 | |
+------------+-----------------+------+-----+---------+----------------+[/tt]
personnel contains the following:
[tt]+----+------------+--------------+-------------------------+------------+
| id | name_first | name_last | role | reports_to |
+----+------------+--------------+-------------------------+------------+
| 1 | Joe | Blow | President | 0 |
| 2 | Fred | Aames | IT Director | 1 |
| 3 | Amy | Barnes | Administration Director | 1 |
| 4 | Niel | Cadway | Sales Director | 1 |
| 5 | Erin | Delpi | Software | 2 |
| 6 | Miles | Ernst | Infrastructure | 2 |
| 7 | John | Farraday | Web design | 5 |
| 8 | John | Gielgud | Desktop design | 5 |
| 9 | A | Webrat | Programmer | 7 |
| 10 | B | Webrat | Programmer | 7 |
| 11 | C | Webrat | Programmer | 7 |
| 12 | D | Webrat | Programmer | 7 |
| 13 | A | Appguy | Programmer | 8 |
| 14 | B | Appguy | Programmer | 8 |
| 15 | C | Appguy | Programmer | 8 |
| 16 | D | Appguy | Programmer | 8 |
| 17 | A | Netguy | Networking | 6 |
| 18 | B | Netguy | Networking | 6 |
| 19 | Richard | Harris | Accounting | 3 |
| 20 | Ralph | Ivers | HR | 3 |
| 21 | A | Beancounter | AR | 19 |
| 22 | B | Beancounter | AP | 19 |
| 23 | A | Salesreptile | Sales | 4 |
| 24 | B | Salesreptile | Sales | 4 |
| 25 | C | Salesreptile | Sales | 4 |
| 26 | D | Salesreptile | Sales | 4 |
+----+------------+--------------+-------------------------+------------+[/tt]
The script below will print something like an org chart. It's not the traditional apex-at-the-center-top kind of chart. The script produces a table. The highest boss is in the upper lefthand corner, his/her subordinates begin one row down in the next column to the right, etc. Each cell of the table has a link to a script from which you could edit a person's record.
WARNING! WARNING! DANGER WILL ROBINSON! THIS SCRIPT USES RECURSION!
The core of the script is the function subordinates(). It takes as inputs the current boss, then it retrieves and prints his data. Then it finds the current boss' subordinates, and calls itself once for each subordinate, with that subordinate as the "new" current boss.
[tt]
Code:
<?php
function subordinates ($superior, $right)
{
global $link;
$query = "SELECT * FROM personnel WHERE id = $superior";
$resource1 = mysql_query ($query, $link);
if ($resource1 !== FALSE)
{
$result = mysql_fetch_object ($resource1);
print "\n<tr>";
if ($right > 1)
{
print "\n\t<td colspan=";
print $right - 1;
print '> </td>';
}
print "\n\t<td>\n";
print "\t\t<a href=\"/foo/update_person_data.php?id=$result->id\">\n";
print "\t\t\t$result->name_first $result->name_last\n";
print "\t\t</a><br>\n";
print "\t\t$result->role\n";
print "\t</td>\n</tr>\n";
$query = "SELECT id FROM personnel WHERE reports_to = $superior ORDER BY name_last, name_first";
$resource2 = mysql_query ($query, $link);
if ($resource2 !== FALSE)
{
while (list ($id) = mysql_fetch_array ($resource2))
{
subordinates ($id, $right + 1);
}
}
}
}
$link = mysql_connect ('localhost', 'test', 'test') or die ('Could not connect: '.mysql_error($link));
mysql_selectdb ('test', $link) or die ('Could not select database :'.mysql_error($link));
print "<html><body><table border=0>\n";
subordinates (1, 1);
print "\n</table></body></html>";
?>
[/tt] ______________________________________________________________________
Never forget that we are
made of the stuff of stars