Пример #1
0
 /**
  * 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;
 }