GIT repositories

Index page of all the GIT repositories that are clonable form this server via HTTPS. Übersichtsseite aller GIT-Repositories, die von diesem Server aus über git clone (HTTPS) erreichbar sind.

Services

A bunch of service scripts to convert, analyse and generate data. Ein paar Services zum Konvertieren, Analysieren und Generieren von Daten.

GNU octave web interface

A web interface for GNU Octave, which allows to run scientific calculations from netbooks, tables or smartphones. The interface provides a web form generator for Octave script parameters with pre-validation, automatic script list generation, as well presenting of output text, figures and files in a output HTML page. Ein Webinterface für GNU-Octave, mit dem wissenschaftliche Berechnungen von Netbooks, Tablets oder Smartphones aus durchgeführt werden können. Die Schnittstelle beinhaltet einen Formulargenerator für Octave-Scriptparameter, mit Einheiten und Einfabevalidierung. Textausgabe, Abbildungen und generierte Dateien werden abgefangen und in einer HTML-Seite dem Nutzer als Ergebnis zur Verfügung gestellt.

Dateisystem-Klasse

FileSystem class

Well, there is not much to say about it. Its mainly a wrapper for the normal file system functions of PHP, except that it works with exceptions and has recursive functions. Risk a glance what you can do with it. The usage example is here:

Nun, es gibt darüber eigentlich nicht viel zu sagen. Die Klasse ist hauptsächlich ein Wrapper für die PHP Dateisystem-Funktionen. Die Klasse arbeitet lediglich mit Exceptions und es sind ein paar rekursive Funktionen implementiert, die das Leben leichter machen. Der Beispiel-Quelltext ist hier:

Sample source code

Anwendungsbeispiel

<?php
require_once('swlib/swlib.class.php');
use sw\FileSystem as fs;
 
//
// Example function
//
function filesystem_example() {
 
  // Get the temp directory
  $tmp_dir = fs::getTempDirectory();
  $my_dir  = fs::getTempFileName();
 
  // Boolean check methods
  $tmp_dir_exists     = (int) fs::exists($tmp_dir);
  $tmp_dir_is_dir     = (int) fs::isDirectory($tmp_dir);
  $tmp_dir_is_file    = (int) fs::isFile($tmp_dir);
  $tmp_dir_is_link    = (int) fs::isLink($tmp_dir);
  $tmp_dir_readable   = (int) fs::isReadable($tmp_dir);
  $tmp_dir_writable   = (int) fs::isWritable($tmp_dir);
  $tmp_dir_executable = (int) fs::isExecutable($tmp_dir);
 
  // The usual file system actions ...
  fs::mkdir($my_dir);
  fs::chdir($my_dir);
  fs::chmod($my_dir, 0777);
 
  //
  // We expect exceptions here because we are not root when running this example.
  //
  try {
    fs::chown($my_dir, 'root');
  } catch(\Exception $e) {
    $chown_exception = $e->getMessage();
    unset($e);
  }
  try {
    fs::chgroup($my_dir, 'root');
  } catch(\Exception $e) {
    $chgrp_exception = $e->getMessage();
    unset($e);
  }
 
  //
  // Let's work with a file:
  //
  $file = 'test.txt';
 
  // Read / write
  fs::writeFile($file, "HELLO");
  $my_file_contents = fs::readFile($file);
 
  // Mode, user, group, size, last modified
  $file_mode   = fs::getFileModeString($file);
  $file_user   = fs::getUserName($file);
  $file_group  = fs::getGroupName($file);
  $file_size   = fs::getFileSize($file);
  $file_mtime_old  = fs::getLastModified($file);
 
  // Change last modified time
  fs::touch($file, $file_mtime_old - 3600);
 
  // Some file path related methods
  $file_basename = fs::getBasename($file);
  $file_extension = fs::getExtension($file);
  $file_dirname = fs::getDirname($file);
  $file_name_no_ext = fs::getFileNameWithoutExtension($file);
 
  // Copy, rename, move, unlink, delete, find recursively
  $file1 = "$file_name_no_ext.1.txt";
  $file2 = "$file_name_no_ext.2.txt";
 
  fs::copy($file, $file1);
  fs::rename($file1, $file2);
 
  $file_list = fs::find($my_dir, '*.txt');
 
  fs::unlink($file2);
  $file2_was_deleted = (int) !fs::exists($file2);
 
  fs::move($file, $file1);
 
  fs::delete($my_dir); // This is RECURSIVE
 
  $my_dir_was_deleted = (int) !fs::exists($my_dir);
 
  //
  // Print out our results saved in variables.
  //
  $vars = get_defined_vars();
  print_r($vars);
}
 
// Run the example
filesystem_example();

Output

Ausgabe

$ php filesystem.php 
 
Array
(
    [tmp_dir] => /tmp
    [my_dir] => /tmp/xj0wh
    [tmp_dir_exists] => 1
    [tmp_dir_is_dir] => 1
    [tmp_dir_is_file] => 0
    [tmp_dir_is_link] => 1
    [tmp_dir_readable] => 1
    [tmp_dir_writable] => 1
    [tmp_dir_executable] => 1
    [chown_exception] => Failed to change file owner of "/tmp/xj0wh" to "root"
    [chgrp_exception] => Failed to change file group of "/tmp/xj0wh" to "root"
    [file] => test.txt
    [my_file_contents] => HELLO
    [file_mode] => -rw-r--r--
    [file_user] => cerberos
    [file_group] => wheel
    [file_size] => 5
    [file_mtime_old] => 1377857474
    [file_basename] => test.txt
    [file_extension] => txt
    [file_dirname] => .
    [file_name_no_ext] => test
    [file1] => test.1.txt
    [file2] => test.2.txt
    [file_list] => Array
        (
            [0] => /tmp/xj0wh/test.2.txt
            [1] => /tmp/xj0wh/test.txt
        )
 
    [file2_was_deleted] => 1
    [my_dir_was_deleted] => 1
)

Class source code

Klassen-Quelltext

<?php
 
/**
 * FileSystem operations (in general wrappers for already existing PHP functions)
 * with exceptions. Implemented static functions are e.g. checking if a file,
 * directory, link exists, recursively find files and folders with filtering,
 * single command file I/O, file basename, dirname, extension, and retrieving
 * system directories and temporary files.
 * @gpackage de.atwillys.sw.php.swLib
 * @author Stefan Wilhelm
 * @copyright Stefan Wilhelm, 2007-2010
 * @license GPL
 * @version 1.0
 * @uses FileSystemException
 */
 
namespace sw;
 
class FileSystem {
 
  /**
   * Searches for recursivly files and/or directories excluding defined whildcard
   * patterns (separated with ";", e.g. "*.ignore1;*.ignore2".
   * @param string $directory
   * @param string $pattern
   * @param string $ignore
   * @param bool $onlyFiles
   * @return array
   */
  public static final function find($directory, $pattern='*', $ignore='', $onlyFiles=false) {
    $ignore = (trim($ignore) == '') ? array() : explode(';', $ignore);
    return self::glob_rr($directory, $pattern, $ignore, $onlyFiles);
  }
 
  private static final function glob_rr($directory, $pattern, $ignore, $onlyFiles) {
    $result = array();
    $directory = preg_replace('/(\*|\?|\[)/', '[$1]', rtrim($directory, '/'));
    $files = @glob($directory . '/*', GLOB_NOSORT);
    if (is_array($files) && !empty($files)) {
      foreach ($files as $file) {
        $doignore = false;
        foreach ($ignore as $i) {
          if (fnmatch($i, basename($file))) {
            $doignore = true;
            break;
          }
        }
        if (!$doignore) {
          if (is_dir($file)) {
            if (!$onlyFiles && fnmatch($pattern, basename($file))) {
              $result[] = $file;
            }
            $result = array_merge($result, self::glob_rr($file, $pattern, $ignore, $onlyFiles));
          } else if (fnmatch($pattern, basename($file))) {
            $result[] = $file;
          }
        }
      }
    }
    return $result;
  }
 
  /**
   * Returns the path for a temporary file. The file is already
   * created when the method returns.
   * @return string
   */
  public static final function getTempFile() {
    return tempnam('', 'php_fs_');
  }
 
  /**
   * Returns the path for a possible temporary file. The file is NOT yet
   * created when the method returns.
   * @return string
   */
  public static final function getTempFileName() {
    return self::getTempDirectory() . '/php_fs_' . time() . '_' . uniqid() . '.tmp';
  }
 
  /**
   * Returns the php temp directory
   * @return string
   */
  public static final function getTempDirectory() {
    return rtrim(sys_get_temp_dir(), '/');
  }
 
  /**
   * Creates a directory recursivly
   * @param string $directory
   * @param int $mode
   */
  public static final function mkdir($directory, $mode=0770) {
    $directory = trim($directory);
    if (is_dir($directory)) {
      throw new FileSystemException('The directory you want to create already exists');
    } else if (is_file($directory)) {
      throw new FileSystemException('The directory you want to create is already an existing file');
    } else if (empty($directory)) {
      throw new FileSystemException('You did not specify a directory to create (empty string given)');
    } else if (!@mkdir($directory, $mode, true)) {
      if (!is_writable(dirname($directory))) {
        throw new FileSystemException('Failed to create directory (parent directory not writable for you)');
      } else {
        throw new FileSystemException('Failed to create directory');
      }
    }
  }
 
  /**
   * Deletes a file or a directory. Directories are deleted RECURSIVLY.
   * @param string $fileOrDirectory
   */
  public static final function delete($fileOrDirectory) {
    $fileOrDirectory = trim($fileOrDirectory);
    if (is_file($fileOrDirectory)) {
      if (!@unlink($fileOrDirectory)) {
        if (!is_writable($fileOrDirectory)) {
          throw new FileSystemException('Failed to delete file (not writable for you): ":file"', array(':file' => $fileOrDirectory));
        } else {
          throw new FileSystemException('Failed to delete file: ":file"', array(':file' => $fileOrDirectory));
        }
      }
    } else if (is_dir($fileOrDirectory)) {
      if (!is_writable($fileOrDirectory)) {
        // This is to prevent deleting files and subfolders but not the
        // directory itself. This can prevent mistakes.
        throw new FileSystemException('Directory to delete is not writable for you: ":file"', array(':file' => $fileOrDirectory));
      } else {
        // Remove files
        $list = self::find($fileOrDirectory, '*', '', true);
        foreach ($list as $file) {
          // use of this method again to get exceptions thrown
          self::delete($file);
        }
        // Remove now empty subdirectories
        $list = array_reverse(self::find($fileOrDirectory, '*', '', false));
        foreach ($list as $dir) {
          if (!rmdir($dir)) {
            throw new FileSystemException('Failed to delete sub directory: ":dir"', array(':dir' => $dir));
          }
        }
        // Remove the directory itself
        if (!@rmdir($fileOrDirectory)) {
          throw new FileSystemException('Failed to delete directory: ":dir"', array(':dir' => $fileOrDirectory));
        }
      }
    } else {
      throw new FileSystemException('File or directory to remove does not exist: ":dir"', array(':dir' => $fileOrDirectory));
    }
  }
 
  /**
   * Deletes a single file or link
   * @param string $file
   */
  public static function unlink($file) {
    if (!@unlink($file)) {
      $e = 'Failed to delete file ":file"';
      if (!file_exists($file)) {
        throw new FileSystemException("$e: No such file or link", array(':file' => $file));
      } else if (!is_writable($file)) {
        throw new FileSystemException("$e: Not writable.", array(':file' => $file));
      } else {
        throw new FileSystemException("$e", array(':file' => $file));
      }
    }
  }
 
  /**
   * Renames a file or directory
   * @param string $src
   * @param string $dest
   */
  public static function rename($src, $dest) {
    if (!@rename($src, $dest)) {
      $e = 'Failed to rename file ":src" to ":dest"';
      if (!file_exists($src)) {
        throw new FileSystemException("$e: No such file or directory.", array(':src' => $src, ':dest' => $dest));
      } else if (!is_writable($src)) {
        throw new FileSystemException("$e: Not writable.", array(':src' => $src, ':dest' => $dest));
      } else {
        throw new FileSystemException("$e", array(':src' => $src, ':dest' => $dest));
      }
    }
  }
 
  /**
   * Moves a file or directory to another location (identical to rename, this
   * function is only for the sake of nice exceptions.)
   * @param string $src
   * @param string $dest
   */
  public static function move($src, $dest) {
    if (!@rename($src, $dest)) {
      $e = 'Failed to move file ":src" to ":dest"';
      if (!file_exists($src)) {
        throw new FileSystemException("$e: No such file or directory.", array(':src' => $src, ':dest' => $dest));
      } else if (!is_writable($src)) {
        throw new FileSystemException("$e: Not writable.", array(':src' => $src, ':dest' => $dest));
      } else {
        throw new FileSystemException("$e", array(':src' => $src, ':dest' => $dest));
      }
    }
  }
 
  /**
   * Copies a file to another location
   * @param string $src
   * @param string $dest
   * @param bool $recursive=false
   */
  public static function copy($src, $dest, $recursive=false) {
    $e = 'Failed to copy file ":src" to ":dest"';
    if (is_file($src)) {
      if (!@copy($src, $dest)) {
        if (!is_readable($src)) {
          throw new FileSystemException("$e: Source file not readable.", array(':src' => $src, ':dest' => $dest));
        } else if (!is_dir(dirname($dest))) {
          throw new FileSystemException("$e: Destination directory does not exist.", array(':src' => $src, ':dest' => $dest));
        } else if (!file_exists($dest) && !is_writable($dest)) {
          throw new FileSystemException("$e: Destination file cannot be overwritten because it is not writable for you.", array(':src' => $src, ':dest' => $dest));
        } else {
          throw new FileSystemException("$e", array(':src' => $src, ':dest' => $dest));
        }
      }
    } else if (is_dir($src)) {
      if (!$recursive) {
        throw new FileSystemException("$e: Source is a directory and no recursive copying is specified", array(':src' => $src, ':dest' => $dest));
      }
      self::mkdir($dest);
      foreach (scandir($src, SCANDIR_SORT_NONE) as $f) {
        if ($f == '.' || $f == '..') {
          continue;
        } else if (is_dir($f)) {
          self::copy("$src/$f", "$dest/$f", true);
        } else {
          self::copy("$src/$f", "$dest/$f", false);
        }
      }
    } else {
      throw new FileSystemException("$e: Source file/dirirectory does not exist.", array(':src' => $src, ':dest' => $dest));
    }
  }
 
  /**
   * Change directory
   * @param string $path
   */
  public static function chdir($path) {
    if(!@chdir($path)) {
      $e = "Could not change directory to :dir";
      if(!is_dir($path)) {
        throw new FileSystemException("$e: Does not exist.", array(':dir' => $path));
      } else if(!is_readable($path)) {
        throw new FileSystemException("$e: Not readable.", array(':dir' => $path));
      } else {
        throw new FileSystemException("$e", array(':dir' => $path));
      }
    }
  }
 
  /**
   * Changes the file/directory mode
   * @param string $fileOrDirectory
   * @param int $mode
   */
  public static function chmod($fileOrDirectory, $mode) {
    if (!chmod($fileOrDirectory, $mode)) {
      $e = 'Failed to change file mode of ":file" to ":mode"';
      if (!file_exists($fileOrDirectory)) {
        throw new FileSystemException("$e: No such file or directory.", array(':file' => $fileOrDirectory, ':mode' => decoct($mode)));
      } else if (!is_writable($fileOrDirectory)) {
        throw new FileSystemException("$e: Not writable.", array(':file' => $fileOrDirectory, ':mode' => decoct($mode)));
      } else {
        throw new FileSystemException("$e", array(':file' => $fileOrDirectory, ':mode' => decoct($mode)));
      }
    }
  }
 
  /**
   * Changes the file/directory ower
   * @param string $fileOrDirectory
   * @param string $owner
   */
  public static function chown($fileOrDirectory, $owner) {
    if (!chown($fileOrDirectory, $owner)) {
      $e = 'Failed to change file owner of ":file" to ":owner"';
      if (!file_exists($fileOrDirectory)) {
        throw new FileSystemException("$e: No such file or directory.", array(':file' => $fileOrDirectory, ':owner' => $owner));
      } else if (!is_writable($fileOrDirectory)) {
        throw new FileSystemException("$e: Not writable.", array(':file' => $fileOrDirectory, ':owner' => $owner));
      } else {
        throw new FileSystemException("$e", array(':file' => $fileOrDirectory, ':owner' => $owner));
      }
    }
  }
 
  /**
   * Changes the file/directory group
   * @param string $fileOrDirectory
   * @param string $group
   */
  public static function chgroup($fileOrDirectory, $group) {
    if (!chgrp($fileOrDirectory, $group)) {
      $e = 'Failed to change file group of ":file" to ":group"';
      if (!file_exists($fileOrDirectory)) {
        throw new FileSystemException("$e: No such file or directory.", array(':file' => $fileOrDirectory, ':group' => $group));
      } else if (!is_writable($fileOrDirectory)) {
        throw new FileSystemException("$e: Not writable.", array(':file' => $fileOrDirectory, ':group' => $group));
      } else {
        throw new FileSystemException("$e", array(':file' => $fileOrDirectory, ':group' => $group));
      }
    }
  }
 
  /**
   * Modifies modification/access time of a file or directory
   * @param string $fileOrDirectory
   * @param int $mtime=null
   * @param int $atime=null
   */
  public static function touch($fileOrDirectory, $mtime=null, $atime=null) {
    if($atime === null) $atime = fileatime($fileOrDirectory);
    if($mtime === null) $mtime = filemtime($fileOrDirectory);
    if(!@touch($fileOrDirectory, $time, $atime)) {
      throw new FileSystemException("Failed to modify mtime/atime of file :file", array(':file' => $fileOrDirectory));
    }
  }
 
  /**
   * Returns if a file or directory exists
   * @param string $fileOrDirectory
   * @return bool
   */
  public static function exists($fileOrDirectory) {
    return file_exists($fileOrDirectory) ? true : false;
  }
 
  /**
   * Returns if a directory exists
   * @param string $fileOrDirectory
   * @return bool
   */
  public static function isDirectory($fileOrDirectory) {
    return is_dir($fileOrDirectory) ? true : false;
  }
 
  /**
   * Returns if a file exists
   * @param string $fileOrDirectory
   * @return bool
   */
  public static function isFile($fileOrDirectory) {
    return is_file($fileOrDirectory) ? true : false;
  }
 
  /**
   * Returns if a file/directory is executable
   * @param string $fileOrDirectory
   * @return bool
   */
  public static function isExecutable($fileOrDirectory) {
    return is_executable($fileOrDirectory) ? true : false;
  }
 
  /**
   * Returns if a file/directory is readable
   * @param string $fileOrDirectory
   * @return bool
   */
  public static function isReadable($fileOrDirectory) {
    return is_readable($fileOrDirectory) ? true : false;
  }
 
  /**
   * Returns if a file/directory is writable
   * @param string $fileOrDirectory
   * @return bool
   */
  public static function isWritable($fileOrDirectory) {
    return is_writable($fileOrDirectory) ? true : false;
  }
 
  /**
   * Returns if a file/directory path is a link
   * @param string $fileOrDirectory
   * @return bool
   */
  public static function isLink($fileOrDirectory) {
    return is_link($fileOrDirectory) ? true : false;
  }
 
  /**
   * Returns the content of a file specified by its path.
   * @param string $file
   * @return string
   */
  public static function & readFile($file) {
    $hFile = @fopen($file, 'rb');
    if (!$hFile) {
      if (!is_string($file)) {
        throw new FileSystemException('The name of the file to read is invalid (no text): :file', array(':file' => $file));
      } else if (!is_file($file)) {
        throw new FileSystemException('The file to read does not exist: :file', array(':file' => $file));
      } else if (!is_readable($file)) {
        throw new FileSystemException('The file to read is not readable for you: :file', array(':file' => $file));
      } else {
        throw new FileSystemException('Unknown error opening file: :file', array(':file' => $file));
      }
    } else {
      $data = '';
      while (!@feof($hFile)) {
        $data .= @fread($hFile, 8192);
        if ($data === false) {
          @fclose($hFile);
          throw new FileSystemException('Failed to read file: :file', array(':file' => $file));
        }
      }
      fclose($hFile);
    }
    return $data;
  }
 
  /**
   * Writes data in a file
   * @param string $file
   * @param mixed $data
   */
  public static function writeFile($file, $data) {
    if (@file_put_contents($file, $data, FILE_BINARY) === false) {
      if (!is_writable($file)) {
        throw new FileSystemException('File cannot be saved because it is not writable for you: :file', array(':file' => $file));
      } else if (is_dir($file)) {
        throw new FileSystemException('File cannot be saved because it already exists as a directory: :file', array(':file' => $file));
      } else if (!is_dir(dirname($file))) {
        throw new FileSystemException('File cannot be saved because the parent directory does not exist: :file', array(':file' => $file));
      } else if (!is_writable(dirname($file)) || !is_executable(dirname($file))) {
        throw new FileSystemException('File cannot be saved because the parent directory is not writable for you and the file would have to be created: :file', array(':file' => $file));
      } else {
        throw new FileSystemException('File could not be saved because an unknown error occurred: :file', array(':file' => $file));
      }
    }
  }
 
  /**
   * Returns the extension of a file/directory
   * @param string $filepath
   * @return string
   */
  public static function getExtension($filepath) {
    return trim(pathinfo(basename($filepath), PATHINFO_EXTENSION));
  }
 
  /**
   * Returns the basename of a file/directory and removed the suffix if specified
   * @param string $filepath
   * @param string $suffix
   * @return string
   */
  public static function getBasename($filepath, $suffix=null) {
    return basename($filepath, $suffix);
  }
 
  /**
   * Returns the directory name of a file/directory
   * @param string $filepath
   * @return string
   */
  public static function getDirname($filepath) {
    return dirname($filepath);
  }
 
  /**
   * Returns the file size of a file in bytes
   * @param string $filepath
   * @return int
   */
  public static function getFileSize($filepath) {
    if (!is_file($filepath)) {
      throw new FileSystemException('File to get the size of does not exist: :file', array(':file' => $filepath));
    } else {
      return filesize($filepath);
    }
  }
 
  /**
   * Returns the last modified timestamp of the file
   * @param string $fileOrDorectory
   * @return int
   */
  public static function getLastModified($fileOrDorectory) {
    $t = filemtime($fileOrDorectory);
    if ($t === false) {
      if (!file_exists($file)) {
        throw new FileSystemException('The file to get last-modified from does not exist: :file', array(':file' => $fileOrDorectory));
      } else if (!is_readable($file)) {
        throw new FileSystemException('The file to get last-modified from is not readable for you: :file', array(':file' => $fileOrDorectory));
      } else {
        throw new FileSystemException('Unknown error getting last-modified: :file', array(':file' => $fileOrDorectory));
      }
    }
    return $t;
  }
 
  /**
   * Returns the file basename without the file extension / suffix
   * @param string $filepath
   * @return string
   */
  public static function getFileNameWithoutExtension($filepath) {
    $filepath = explode('.', trim($filepath));
    if (count($filepath) == 2 && reset($filepath) == '') {
      // This is a hidden .something file
    } else if (count($filepath) > 1) {
      array_pop($filepath);
    }
    $filepath = implode('.', $filepath);
    return $filepath;
  }
 
  /**
   * Get GID of a File or Directory
   * @param string $fileOrDorectory
   * @return int
   * @throws FileSystemException
   */
  public static function getUserId($fileOrDorectory) {
    $stat = stat($fileOrDorectory);
    if ($stat === false) {
      if (!file_exists($file)) {
        throw new FileSystemException('The file to get user id from does not exist: :file', array(':file' => $fileOrDorectory));
      } else if (!is_readable($file)) {
        throw new FileSystemException('The file to get user id from is not readable for you: :file', array(':file' => $fileOrDorectory));
      } else {
        throw new FileSystemException('Unknown error getting user id: :file', array(':file' => $fileOrDorectory));
      }
    }
    return $stat[4];
  }
 
  /**
   * Get GID of a File or Directory
   * @param string $fileOrDorectory
   * @return int
   * @throws FileSystemException
   */
  public static function getGroupId($fileOrDorectory) {
    $stat = stat($fileOrDorectory);
    if ($stat === false) {
      if (!file_exists($file)) {
        throw new FileSystemException('The file to get group from does not exist: :file', array(':file' => $fileOrDorectory));
      } else if (!is_readable($file)) {
        throw new FileSystemException('The file to get group from is not readable for you: :file', array(':file' => $fileOrDorectory));
      } else {
        throw new FileSystemException('Unknown error getting group: :file', array(':file' => $fileOrDorectory));
      }
    }
    return $stat[5];
  }
 
  /**
   * Returns the name of the group given by int $gid
   * @staticvar array $grps
   * @param int $path
   * @return string
   */
  public static function getGroupName($path) {
    static $grps = array();
    $path = self::getGroupId($path);
    if(!isset($grps[$path])) $grps[$path] = ($g = @posix_getgrgid($path))===false ? $path : trim($g['name']);
    return $grps[$path];
  }
 
  /**
   * Returns the name of the user given by int $uid
   * @staticvar array $usrs
   * @param int $path
   * @return string
   */
  public static function getUserName($path) {
    static $usrs = array();
    $path = self::getUserId($path);
    if(!isset($usrs[$path])) $usrs[$path] = ($u = @posix_getpwuid($path))===false ? $path : trim($u['name']);
    return $usrs[$path];
  }
 
  /**
   * Returns the file mode/permissions as string, e.g. '-rw-r--r--', 'lrwx-r--r--',
   * 'drwxr-xr-x'.
   * @staticvar string $tp
   * @param string $file
   * @return string
   */
  public static function getFileModeString($file) {
    static $tp = "upcddbb--llssuu";
    $p = fileperms($file);
    return $tp[($p>>12) & 0xf] .
      (($p & 0x0100) ? 'r' : '-') . (($p & 0x0080) ? 'w' : '-') . (($p & 0x0040) ? (($p & 0x0800) ? 's' : 'x' ) : (($p & 0x0800) ? 'S' : '-')) .
      (($p & 0x0020) ? 'r' : '-') . (($p & 0x0010) ? 'w' : '-') . (($p & 0x0008) ? (($p & 0x0400) ? 's' : 'x' ) : (($p & 0x0400) ? 'S' : '-')) .
      (($p & 0x0004) ? 'r' : '-') . (($p & 0x0002) ? 'w' : '-') . (($p & 0x0001) ? (($p & 0x0200) ? 't' : 'x' ) : (($p & 0x0200) ? 'T' : '-'));
  }
 
  /**
   * Returns the first file found defined by the array $fnmatch_patterns (which
   * contains wildcard patterns). As the array is processed sequentially this
   * method allows to priorise which file is returned. If no files are matched
   * or on invalid input the method returns an empty string.
   * NOTE: This method does NOT recurse through directories to save time,
   *       patterns like "/tmp/my-config/*.d/Makefile" will NOT work,
   *       but e.g. "/tmp/my-config/*.am" will work.
   * @param array $fnmatch_patterns
   * @param bool $case_insensitive
   * @return string
   */
  public static function getOneOf($fnmatch_patterns, $case_sensitive=true) {
    if(is_string($fnmatch_patterns)) $fnmatch_patterns = array(0=>$fnmatch_patterns);
    if(!is_array($fnmatch_patterns)) return '';
    $flags = $case_sensitive ? 0 : FNM_CASEFOLD;
    foreach($fnmatch_patterns as $pattern) {
      $pt = basename($pattern);
      $dn = strpos($pattern, '/') !== false ? @dirname($pattern) : @getcwd();
      if(($dh = @opendir($dn)) !== false) {
        while (($file = readdir($dh)) !== false) {
          if($file == '.' || $file == '..') continue;
          if(@fnmatch($pt, $file, $flags)) {
            @closedir($dh); return "$dn/$file";
          }
        }
        @closedir($dh);
      }
    }
    return '';
  }
 
}