/** * This function performs exactly as readSource, but with two additional parameters * ($reachable and $baseDir) that will be set so that $reachable."/".$baseDir == $URL * and $reachable can be reached (in case of error) * * @access private */ function _readSource(&$toConvert, $URL, &$reachable, &$baseDir, $symbolic = null, $uncompression = 0, $directoryDepth = -1) { $source =& File_Archive::_convertToReader($toConvert); if (PEAR::isError($source)) { return $source; } if (is_array($URL)) { $converted = array(); foreach ($URL as $key => $foo) { $converted[] =& File_Archive::_convertToReader($URL[$key]); } return File_Archive::readMulti($converted); } //No need to uncompress more than $directoryDepth //That's not perfect, and some archives will still be uncompressed just //to be filtered out :( if ($directoryDepth >= 0) { $uncompressionLevel = min($uncompression, $directoryDepth); } else { $uncompressionLevel = $uncompression; } require_once 'File/Archive/Reader.php'; $std = File_Archive_Reader::getStandardURL($URL); //Modify the symbolic name if necessary $slashPos = strrpos($std, '/'); if ($symbolic === null) { if ($slashPos === false) { $realSymbolic = $std; } else { $realSymbolic = substr($std, $slashPos + 1); } } else { $realSymbolic = $symbolic; } if ($slashPos !== false) { $baseFile = substr($std, 0, $slashPos + 1); $lastFile = substr($std, $slashPos + 1); } else { $baseFile = ''; $lastFile = $std; } if (strpos($lastFile, '*') !== false || strpos($lastFile, '?') !== false) { //We have to build a regexp here $regexp = str_replace(array('\\*', '\\?'), array('[^/]*', '[^/]'), preg_quote($lastFile)); $result = File_Archive::_readSource($source, $baseFile, $reachable, $baseDir, null, 0, -1); return File_Archive::filter(File_Archive::predPreg('/^' . $regexp . '$/'), $result); } //If the URL can be interpreted as a directory, and we are reading from the file system if ((empty($URL) || is_dir($URL)) && $source === null) { require_once "File/Archive/Reader/Directory.php"; if ($uncompressionLevel != 0) { require_once "File/Archive/Reader/Uncompress.php"; $result = new File_Archive_Reader_Uncompress(new File_Archive_Reader_Directory($std, '', $directoryDepth), $uncompressionLevel); } else { $result = new File_Archive_Reader_Directory($std, '', $directoryDepth); } if ($directoryDepth >= 0) { require_once 'File/Archive/Reader/Filter.php'; require_once 'File/Archive/Predicate/MaxDepth.php'; $tmp =& File_Archive::filter(new File_Archive_Predicate_MaxDepth($directoryDepth), $result); unset($result); $result =& $tmp; } if (!empty($realSymbolic)) { if ($symbolic === null) { $realSymbolic = ''; } require_once "File/Archive/Reader/ChangeName/AddDirectory.php"; $tmp = new File_Archive_Reader_ChangeName_AddDirectory($realSymbolic, $result); unset($result); $result =& $tmp; } //If the URL can be interpreted as a file, and we are reading from the file system } else { if (is_file($URL) && substr($URL, -1) != '/' && $source === null) { require_once "File/Archive/Reader/File.php"; $result = new File_Archive_Reader_File($URL, $realSymbolic); //Else, we will have to build a complex reader } else { require_once "File/Archive/Reader/File.php"; $realPath = $std; // Try to find a file with a known extension in the path ( // (to manage URLs like archive.tar/directory/file) $pos = 0; do { if ($pos + 1 < strlen($realPath)) { $pos = strpos($realPath, '/', $pos + 1); } else { $pos = false; } if ($pos === false) { $pos = strlen($realPath); } $file = substr($realPath, 0, $pos); $baseDir = substr($realPath, $pos + 1); $dotPos = strrpos($file, '.'); $extension = ''; if ($dotPos !== false) { $extension = substr($file, $dotPos + 1); } } while ($pos < strlen($realPath) && (!File_Archive::isKnownExtension($extension) || is_dir($file) && $source == null)); $reachable = $file; //If we are reading from the file system if ($source === null) { //Create a file reader $result = new File_Archive_Reader_File($file); } else { //Select in the source the file $file require_once "File/Archive/Reader/Select.php"; $result = new File_Archive_Reader_Select($file, $source); } require_once "File/Archive/Reader/Uncompress.php"; $tmp = new File_Archive_Reader_Uncompress($result, $uncompressionLevel); unset($result); $result = $tmp; //Select the requested folder in the uncompress reader $isDir = $result->setBaseDir($std); if (PEAR::isError($isDir)) { return $isDir; } if ($isDir && $symbolic == null) { //Default symbolic name for directories is empty $realSymbolic = ''; } if ($directoryDepth >= 0) { //Limit the maximum depth if necessary require_once "File/Archive/Reader/Filter.php"; require_once "File/Archive/Predicate/MaxDepth.php"; $tmp = new File_Archive_Reader_Filter(new File_Archive_Predicate($directoryDepth + substr_count(substr($std, $pos + 1), '/')), $result); unset($result); $result =& $tmp; } if ($std != $realSymbolic) { require_once "File/Archive/Reader/ChangeName/Directory.php"; //Change the base name to the symbolic one if necessary $tmp = new File_Archive_Reader_ChangeName_Directory($std, $realSymbolic, $result); unset($result); $result =& $tmp; } } } $cacheCondition = File_Archive::getOption('cacheCondition'); if ($cacheCondition !== false && preg_match($cacheCondition, $URL)) { $tmp =& File_Archive::cache($result); unset($result); $result =& $tmp; } return $result; }