/**
 * Recursively scan filesystem for files
 *
 * @param string  $dir_path
 * @param string  $regex    (optional) to filter filenames with
 * @param string  $prepend  (optional)
 * @return array file names
 */
function air2_dirscan($dir_path, $regex = '//', $prepend = '')
{
    if (!is_dir($dir_path)) {
        return false;
    }
    $files = array();
    $dirs = array();
    $scan = scandir($dir_path);
    // add files at this level first
    foreach ($scan as $file) {
        // remove hidden/meta directories
        if (!preg_match('/^\\./', $file)) {
            $full = $prepend . $file;
            if (is_dir("{$dir_path}/{$file}")) {
                $dirs[$full] = "{$dir_path}/{$file}";
            } else {
                if (preg_match($regex, $file)) {
                    $files[] = $full;
                }
            }
        }
    }
    // now process subdirectories
    foreach ($dirs as $name => $path) {
        $files = array_merge($files, air2_dirscan($path, $regex, $name . '/'));
    }
    return $files;
}
 /**
  * Get an array of css includes
  *
  * @return array $css
  */
 public function css_includes()
 {
     // only need compressed file, if it exists
     if (file_exists(AIR2_DOCROOT . '/css/air2-compressed.css')) {
         return array(air2_uri_for('css/air2-compressed.css'));
     }
     // recursively scan css directory
     $css = air2_dirscan(AIR2_DOCROOT . '/css/', '/.css$/');
     $rmv = array('docbook.css', 'login.css', 'ie.css', 'print.css', 'ext-theme-air2.css', 'query.css', 'pinform.css', 'third_party.css');
     air2_array_remove($rmv, $css);
     // change to absolute paths
     foreach ($css as &$file) {
         $mtime = filemtime(AIR2_DOCROOT . '/css/' . $file);
         $file = air2_uri_for("css/{$file}", array('_' => $mtime));
     }
     return $css;
 }