DOM/AJAX/PHP File Browser

17 Mar

Time for a change of pace.

Recently, the HR Dept where I work, approached me as they wanted to be able to update their section of the company Intranet as easily as possible. After looking at their requirements it became clear that what they needed was an area where they could replace old files with new versions of the same file, or add new directories/files, or edit existing directory/file names. Practically, this was easy – they had write access to the main HR directory on the Intranet so it would be a simple case of them dragging and dropping files/directories from their local drives to the HR directory on the Intranet.

The technical challenge for me came from the subsequent need to create a ‘HR file browser’ which would allow all company Intranet users to browse this directory and download selected files in a usable, aesthetically pleasing manner i.e. not just hardlink to the directory and allow them to browse a list of directories.

The obvious answer was to create a DOM driven file browser that would pick up file/directory data from a PHP script. However, I must allow for users that might’ve disabled Javascript or who hadn’t got a certain feature set (getElementById etc).

The script would have four main components:

1) A markup file that contained the actual page and file browser
2) A CSS file to style the elements on this page
3) A Javascript file to manipulate the behaviour of these files
4) A PHP file to read and control access to files and directories

The PHP File

This file contains the ‘guts’ of the webapp. It must be able to:

a) Allow a directory to be defined which is the ‘base’ of the application i.e. the main HR directory in my case. Users should not be able to browse above this base.
b) Get a list of all directories and files within the current directory.
c) Get the file extension of every file so I can dynamically apply a class name and hence style for each file type.
d) Allow a reverse path to be built to display the current path and to build a working ‘back’ button.
e) Make all displayed directories browsable and all displayed files downloadable.
f) It must work and be usable even if the user does not have Javascript/requisite DOM capabilities.
g) Disregard the files that drive this app.

I was lucky enough to already know of the existence of a PHP script that did approx 60% of the work I needed it to so I set about cannibalising and rebuilding this script, taking out the bits I didn’t need and writing in bits I did need. The script as it stood met requirements a), b) and e) so I needed to work on refining those areas and adding in new bits. I won’t go through the whole thing but I do want to discuss certain aspects of it:

Getting the file extension is not difficult:

function get_extension($Filename) {
   $Extension = explode (".", $Filename);
   $Extension_i = (count($Extension) - 1);
   return $Extension[$Extension_i];
}

And neither is reversing the path:

function reverse_strrchr($haystack, $needle){
   $pos = strrpos($haystack, $needle);
   if($pos === false) {
       return $haystack;
   }
   return substr($haystack, 0, $pos);
}

I also had to split the foreach blocks in two as I wanted to rpesent the directories first, then the files – directories have a set style whereas files have a style dependant on their file extension:

echo "<ul>
foreach ($file_array as $file_name) {
      $is_file = DOWNLOAD_PATH . "/$final_path/$file_name";
      if (is_dir($is_file) &amp;&amp; $file_name != "browser-images") {
        print " <li><a class='dir' href='" . $_SERVER&#91;"PHP_SELF"&#93; . "?go=list&amp;
               path=" . urlencode($final_path) . "/" . urlencode($file_name) . "'>" 
               . $file_name . "</a></li>n";
      }
}
echo "</ul>";

echo "<ul id='filepath'>n";
foreach ($file_array as $file_name) {
  $is_file = DOWNLOAD_PATH . "/$final_path/$file_name";				
  if (is_file($is_file) &amp;&amp; $file_name != "browser.php") {
    if(get_extension($file_name) == "css"){
      $ext = "code";
    }else if(get_extension($file_name) == "php"){
      $ext = "php";
    }
   
   ....

   }				
   print " <li><a class='" . $ext . "' href='" .  $_SERVER&#91;"PHP_SELF"&#93; . "?
           go=download&amp;path=" . urlencode($final_path) . "&amp;file="
           . urlencode($file_name) . "'>" . $file_name . "</a></li>n";
 }
		
}
echo "</ul>n";

You might also notice these lines:

if (is_dir($is_file) && $file_name != "browser-images") {

...

if (is_file($is_file) && $file_name != "browser.php"

This tells the script to disregard the file if the directory name is ‘browser-images’ or file name is ‘browser.php’ which is the name of _this_ script – you don’t want people downloading these! (NB: ‘browser-images’ is where I stuck all the images relating to this app).

Most importantly, you need to declare this line:

define("DOWNLOAD_PATH", "/var/www/html/intranet/download");

This must be the ‘base’ path i.e. where you want to start browsing _from_ – users will not be able to browse _above_ this directory but they can browse anywhere within it (recursively).

To check this was working (and to ensure it would work independantly of Javascript) I ran this in the browser – wasn’t very pretty, wasn’t very usable but it was there and it would allow people without JS or the right DOM facilities to use the script.

Onward.

The DOM/Javascript/AJAX Script

This script needed to:

a) Connect to the PHP script above (hereafter referred to as ‘browser.php’) and call the right function to generate the right directory/file list for the directory that browser.php was currently ‘looking’ at.
b) Create animation to allow the file browser itself to appear and disappear as per user requirements.
c) Create a working ‘back’ button (also from the PHP script)
d) Degrade gracefully for those users who were Javascript or DOM-less.

My first issue was that I’d never used Javascript to animate movement before so I relied heavily on a code snippet of Jeremy Keith’s for that. His function allows you to pass in the values of the element you want to animate movement for, where on the x axis, where on the y axis and finally what the movement interval should be). The settings you may need to change are in these lines:

if(!hr.style.left){
  hr.style.left="-300px";
}
	
if(!hr.style.top){
  hr.style.top="70px";
}

Which you need to reflect the starting position of the selected element.

The rest of the code is fairly self explanatory and basically creates an AJAX connection to the PHP script and points the script to the ‘next’ directory and/or file. NB: You will need to specify the path to the file ‘browser.php’. There are three onclick events in this function too – one to browse the files, one to trigger the ‘back’ button and one to trigger the ‘home’ button.

The Stylesheet

The stylesheet is simplified (apologies for any redundancy in it – I think I stripped most of it out after testing but I may have missed the odd thing), but basically, the markup file contains a

with an id of ‘wrap’ to which I applied this style:

div#wrap {
  position: absolute;
  top: 73px;
  left: -300px;
  width: 1170px;
}

A quick glance back at the Javascript code reveals that I specified these are the starting points for my animation. What the animation will do therefore is scroll ‘wrap’ to the right, from its starting point at -300px (i.e. off the screen) and thus reveal it. The ‘close’ button will do the opposite.

You’ll also find all the styles I used for the HR File Browser itself.

The Markup

Finally, there is the markup. A standard XHTML page, its only wrinkle is the presence of two elements: firstly is the empty

with an id of ‘hrResponse’ – this is where I will ‘pipe’ all my dynamic content into. Secondly is the link element that starts the whole thing off:

<li><a title="Browse HR documents" id="openBrowser" href="http://localhost/intranet/download/browser.php">Browse HR documents</a></li>

as you can see the URI is not empty – it contains the path to the ‘browser.php’ file. This is to ensure graceful degradation. If the user has Javascript/DOM capabilities they will get the DOM scripted environment. If the don’t they’ll get sent to the ‘browser.php’ file with no enhancements.

And thats that. You can download it all from here – use it, improve it, distribute it – whatever you like.

Advertisements

6 Responses to “DOM/AJAX/PHP File Browser”

  1. Jemaleddin March 17, 2006 at 18:17 #

    Looks cool – I’ll have to try that out this weekend.

    (Hey, you should set up a little demo site as well.)

  2. brian March 31, 2006 at 20:18 #

    This sounds really cool, but I can’t figure out how to get it to work. It just says “Directory empty”.

    BTW, i really like the comment preview. That’s tite.

    _Brian.

  3. Guyhom May 3, 2006 at 14:13 #

    Same problem. Can’t make it running without “Directory empty”

  4. Kev May 3, 2006 at 14:22 #

    Have you made sure the path reflects the real path? i.e. you’ve changed the settings?

    I’ve just tried it again and it works fine for me. I’ll have a better look at some point to be sure.

  5. Guyhom May 3, 2006 at 14:51 #

    Yes I did. And I checked also the link between html => ‘download’ directory…

  6. Guyhom May 4, 2006 at 11:04 #

    Please, some help ?

Comments are closed.

%d bloggers like this: