[eluser]OwanH[/eluser]
OK so as I promised, here's the code for the controller. I hope the documentation embedded in the code is adequate. Note that the code uses CI's
Active Record class so make sure it is loaded if you decide to run with this code. Let me just say I tested it out and it works like a charm.
Code:
<?php
class Directory_tree_cache extends Controller {
var $test_dir; // our test directory
var $tbl_name = 'directory_tree'; // name of the DB table
// The table 'ptr_directory_tree_root' has at most one (1) row that stores one (1)
// single value; the entry_id of the row containg the root directory info.
//
var $ptr_root_dir_id_tbl = 'ptr_directory_tree_root';
// Contructor
function Directory_tree_cache()
{
// Call parent contructor
parent::Controller();
$this->load->helper('url'); // Load URL helper (for 'redirect' and 'site_url')
$this->load->database(); // Connect to the database
// I'm setting the entire "application" folder as my test directory. Change to suit your needs.
$this->test_dir = APPPATH;
}
function index()
{
// Check if cache exists.
if ($this->db->count_all($this->tbl_name) > 0)
{
$query = $this->db->get($this->ptr_root_dir_id_tbl);
$row = $query->first_row();
redirect("/directory_tree_cache/show_dir/" . $row->root_entry_id);
}
else {
// This redirect will result in the cache being created and the contents
// of the root folder will be shown.
redirect('/directory_tree_cache/show_dir/0');
}
} // index
function show_dir($dir_id)
{
// STEP 1: Let's see if a cache already exists for the folder heirarchy.
if ($this->db->count_all($this->tbl_name) > 0)
{
// STEP 2: If cache exists, get directory contents from it.
$query = $this->db->getwhere($this->tbl_name, "parent_id=$dir_id");
foreach ($query->result() as $row)
{
if ($row->entry_type == 'Folder')
{
$link = site_url('/directory_tree_cache/show_dir/' . $row->entry_id);
$str = '<a href="' . $link . '">' . $row->entry_name . '</a>';
}
else {
$link = site_url('/directory_tree_cache/show_file/' . $row->entry_id);
$str = '<a href="' . $link . '">' . basename($row->entry_name) . '</a>';
}
echo $str . '<br />';
}
}
else {
// STEP 3: If cache does not exist, create it before outputting content structure.
// NOTE: Zero (0) is used as the parent ID value for the info stored on the root
// directory.
$this->db->insert($this->tbl_name, array('entry_name' => $this->test_dir,
'entry_type' => 'Folder', 'parent_id' => 0));
// Store this, we'll need it next few lines.
$insert_id = $this->db->insert_id();
// Now open the test directory and generate a DB cache of the entire tree structure.
$this->_create_cache($this->test_dir, $insert_id);
// Store ID of the row with the root directory info. in our reference table.
$this->db->delete($this->ptr_root_dir_id_tbl, '1');
$this->db->insert($this->ptr_root_dir_id_tbl, array('root_entry_id' => $insert_id));
// Delete DB caches created by CI for this controller, if you have configured CI to
// automatically cache your database queries. If you have NOT activated query caching
// then comment out the following 3 lines.
$this->db->cache_delete('directory_tree_cache', 'index');
$this->db->cache_delete('directory_tree_cache', 'show_dir');
$this->db->cache_delete('directory_tree_cache', 'show_file');
// Redirect and show contents of the root directory.
redirect("/directory_tree_cache/show_dir/$insert_id");
}
} // show_dir
function show_file($file_id)
{
$query = $this->db->getwhere($this->tbl_name, "entry_id=$file_id");
$row = $query->first_row();
// Show the contents of the file.
echo file_get_contents($row->entry_name)
} // show_file
/* @private helper - creates a cache of the directory tree heirarchy. */
function _create_cache($dir, $parent_id)
{
if (substr($dir, strlen($dir)-1, 1) != '/')
$dir .= '/';
if ($handle = @opendir($dir))
{
while ($file = readdir($handle))
{
// Ignore reference to 'self' and parent directories.
if (($file == ".") || ($file == ".."))
continue 1;
if (is_dir($dir . $file))
{
// Sub-directory found, cache info. and go recursive.
$this->db->insert($this->tbl_name, array('entry_name' => $file,
'entry_type' => 'Folder', 'parent_id' => $parent_id));
$this->_create_cache($dir . $file, $this->db->insert_id());
}
elseif (is_file($dir . $file))
{
// File found, simply cache info.
$this->db->insert($this->tbl_name, array('entry_name' => $dir.$file,
'entry_type' => 'File', 'parent_id' => $parent_id));
}
} // end while ($file = readdir($handle))
@closedir($handle); // Prevent resouce deadlock!
}
} // _create_cache
} /* End class Directory_tree_cache */
?>
Hope this proves useful man. Knock urself out.