blob: 41a9cfe7868d77b808335a471981a206a2ff6cae [file] [log] [blame]
<?php
/*
* Script: FileManagerWithAliasSupport.php
* MooTools FileManager - Backend for the FileManager Script (with Alias path mapping support)
*
* Authors:
* - Christoph Pojer (http://cpojer.net) (author)
* - James Ehly (http://www.devtrench.com)
* - Fabian Vogelsteller (http://frozeman.de)
* - Ger Hobbelt (http://hebbut.net)
*
* License:
* MIT-style license.
*
* Copyright:
* FileManager Copyright (c) 2009-2011 [Christoph Pojer](http://cpojer.net)
* Backend: FileManager & FileManagerWithAliasSupport Copyright (c) 2011 [Ger Hobbelt](http://hobbelt.com)
*
* Dependencies:
* - Tooling.php
* - Image.class.php
* - getId3 Library
* - FileManager.php
*/
require(strtr(dirname(__FILE__), '\\', '/') . '/FileManager.php');
/**
* Derived class for FileManager which is capable of handling Aliases as served through Apache's mod_alias or
* mod_vhost_alias, PROVIDED you have set up the Alias translation table in the constructor: you must pass this table in the
* $options array as a mapping array in the constructor.
*
* Options:
* -(all of the options of the FileManager class)
* -Aliases: (associative array of strings, where the 'key' URI path is to be transformed to the 'value' physical filesystem path.
*
* See Demos/FM-common.php::mkNewFileManager() for an example of an 'Aliases' path mapping set.
*/
class FileManagerWithAliasSupport extends FileManager
{
protected $scandir_alias_lu_arr;
public function __construct($options)
{
$this->scandir_alias_lu_arr = null;
$options = array_merge(array(
'Aliases' => null // default is an empty Alias list.
), (is_array($options) ? $options : array()));
parent::__construct($options);
/*
* Now process the Aliases array:
* it works as-is for transforming URI to FILE path, but we need
* to munch the list for scandir() to have fast access at the same info:
*
* here the goal is for scandir() to show the aliases as (fake) directory
* entries, hence we need to collect the aliases per parent directory:
*/
if (is_array($this->options['Aliases']))
{
$alias_arr = $this->options['Aliases'];
// collect the set of aliases per parent directory: we need a fully set up options['directory'] for this now
$scandir_lookup_arr = array();
// NOTE: we can use any of the url2file_path methods here as those only use the raw [Aliases] array
foreach($alias_arr as $uri => $file)
{
$isdir = !is_file($file);
$p_uri = parent::getParentDir($uri);
$a_name = basename($uri);
// as scandir works with filesystem paths, convert this URI path to a filesystem path:
$p_dir = $this->url_path2file_path($p_uri);
$p_dir = self::enforceTrailingSlash($p_dir);
if (!isset($scandir_lookup_arr[$p_dir]))
{
$scandir_lookup_arr[$p_dir] = array(array(), array());
}
$scandir_lookup_arr[$p_dir][!$isdir][] = /* 'alias' => */ $a_name;
}
$this->scandir_alias_lu_arr = $scandir_lookup_arr;
}
}
/**
* @return array the FileManager options and settings.
*/
public function getSettings()
{
return array_merge(array(
'scandir_alias_lu_arr' => $this->scandir_alias_lu_arr
), parent::getSettings());
}
/**
* An augmented scandir() which will ensure any Aliases are included in the relevant
* directory scans; this makes the Aliases behave very similarly to actual directories.
*/
public function scandir($dir, $filemask, $see_thumbnail_dir, $glob_flags_or, $glob_flags_and)
{
$dir = self::enforceTrailingSlash($dir);
// collect the real items first:
$coll = parent::scandir($dir, $filemask, $see_thumbnail_dir, $glob_flags_or, $glob_flags_and);
if ($coll === false)
return $coll;
$flags = GLOB_NODOTS | GLOB_NOHIDDEN | GLOB_NOSORT;
$flags &= $glob_flags_and;
$flags |= $glob_flags_or;
// make sure we keep the guarantee that the '..' entry, when present, is the very last one, intact:
$doubledot = array_pop($coll['dirs']);
if ($doubledot !== null && $doubledot !== '..')
{
$coll['dirs'][] = $doubledot;
$doubledot = null;
}
// we must check against thumbnail path again, as it MAY be an alias, itself!
$tndir = null;
if (!$see_thumbnail_dir)
{
$tn_uri = $this->options['thumbnailPath'];
$tnpath = $this->url_path2file_path($tn_uri);
//if (FileManagerUtility::startswith($dir, $tnpath))
// return false;
$tnparent = self::getParentDir($tnpath);
$just_below_thumbnail_dir = FileManagerUtility::startswith($dir, $tnparent);
if ($just_below_thumbnail_dir)
{
$tndir = basename(substr($tn_uri, 0, -1));
}
}
// now see if we need to add any aliases as elements:
if (isset($this->scandir_alias_lu_arr) && !empty($this->scandir_alias_lu_arr[$dir]))
{
$a_base = $this->scandir_alias_lu_arr[$dir];
$d = $coll['dirs'];
$f = $coll['files'];
foreach($a_base[false] as $a_elem)
{
if (!in_array($a_elem, $d, true) && $tndir !== $a_elem
&& (!($flags & GLOB_NOHIDDEN) || $a_elem[0] != '.') )
{
//$coll['special_indir_mappings'][1][] = array_push($coll['dirs'], $a_elem) - 1;
$coll['dirs'][] = $a_elem;
}
}
foreach($a_base[true] as $a_elem)
{
if (!in_array($a_elem, $f, true)
&& (!($flags & GLOB_NOHIDDEN) || $a_elem[0] != '.') )
{
//$coll['special_indir_mappings'][0][] = array_push($coll['files'], $a_elem) - 1;
$coll['files'][] = $a_elem;
}
}
}
// make sure we keep the guarantee that the '..' entry, when present, is the very last one, intact:
if ($doubledot !== null)
{
$coll['dirs'][] = $doubledot;
}
return $coll;
}
/**
* Return the filesystem absolute path for the relative or absolute URI path.
*
* Takes the ['Aliases'] mapping array into account; it is processed from top to bottom a la mod_alias.
*
* Note: as it uses normalize(), any illegal path will throw an FileManagerException
*
* Returns a fully normalized filesystem absolute path.
*/
public function url_path2file_path($url_path)
{
$url_path = $this->rel2abs_url_path($url_path);
$replaced_some = false;
if (is_array($this->options['Aliases']))
{
$alias_arr = $this->options['Aliases'];
foreach($alias_arr as $a_url => $a_path)
{
// if the uri path matches us (or at least our start), then apply the mapping.
// Make sure to only match entire path elements:
if (FileManagerUtility::startsWith($url_path . '/', $a_url . '/'))
{
$url_path = $a_path . substr($url_path, strlen($a_url));
$replaced_some = true;
}
}
}
if (!$replaced_some)
{
$url_path = parent::url_path2file_path($url_path);
}
return $url_path;
}
/**
* Return the filesystem absolute path for the relative URI path or absolute LEGAL URI path.
*
* Note: as it uses normalize(), any illegal path will throw an FileManagerException
*
* Returns a fully normalized filesystem absolute path.
*/
public function legal_url_path2file_path($url_path)
{
$url_path = $this->rel2abs_legal_url_path($url_path);
$url_path = substr($this->options['directory'], 0, -1) . $url_path;
$path = $this->url_path2file_path($url_path);
return $path;
}
}