AAAAPK 3?\S)I I
folder.phpnu W+A store($sfid, $dfid))
{
return JError::raiseError(-1, JText::_('JLIB_FILESYSTEM_ERROR_COPY_FAILED'));
}
break;
}
}
}
else
{
if (!($dh = @opendir($src)))
{
return JError::raiseError(-1, JText::_('JLIB_FILESYSTEM_ERROR_FOLDER_OPEN'));
}
// Walk through the directory copying files and recursing into folders.
while (($file = readdir($dh)) !== false)
{
$sfid = $src . '/' . $file;
$dfid = $dest . '/' . $file;
switch (filetype($sfid))
{
case 'dir':
if ($file != '.' && $file != '..')
{
$ret = self::copy($sfid, $dfid, null, $force, $use_streams);
if ($ret !== true)
{
return $ret;
}
}
break;
case 'file':
if ($use_streams)
{
$stream = JFactory::getStream();
if (!$stream->copy($sfid, $dfid))
{
return JError::raiseError(-1, JText::_('JLIB_FILESYSTEM_ERROR_COPY_FAILED') . ': ' . $stream->getError());
}
}
else
{
if (!@copy($sfid, $dfid))
{
return JError::raiseError(-1, JText::_('JLIB_FILESYSTEM_ERROR_COPY_FAILED'));
}
}
break;
}
}
}
return true;
}
/**
* Create a folder -- and all necessary parent folders.
*
* @param string $path A path to create from the base path.
* @param integer $mode Directory permissions to set for folders created. 0755 by default.
*
* @return boolean True if successful.
*
* @since 11.1
*/
public static function create($path = '', $mode = 0755)
{
// Initialise variables.
$FTPOptions = JClientHelper::getCredentials('ftp');
static $nested = 0;
// Check to make sure the path valid and clean
$path = JPath::clean($path);
// Check if parent dir exists
$parent = dirname($path);
if (!self::exists($parent))
{
// Prevent infinite loops!
$nested++;
if (($nested > 20) || ($parent == $path))
{
JError::raiseWarning('SOME_ERROR_CODE', __METHOD__ . ': ' . JText::_('JLIB_FILESYSTEM_ERROR_FOLDER_LOOP'));
$nested--;
return false;
}
// Create the parent directory
if (self::create($parent, $mode) !== true)
{
// JFolder::create throws an error
$nested--;
return false;
}
// OK, parent directory has been created
$nested--;
}
// Check if dir already exists
if (self::exists($path))
{
return true;
}
// Check for safe mode
if ($FTPOptions['enabled'] == 1)
{
// Connect the FTP client
jimport('joomla.client.ftp');
$ftp = JFTP::getInstance($FTPOptions['host'], $FTPOptions['port'], null, $FTPOptions['user'], $FTPOptions['pass']);
// Translate path to FTP path
$path = JPath::clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $path), '/');
$ret = $ftp->mkdir($path);
$ftp->chmod($path, $mode);
}
else
{
// We need to get and explode the open_basedir paths
$obd = ini_get('open_basedir');
// If open_basedir is set we need to get the open_basedir that the path is in
if ($obd != null)
{
if (JPATH_ISWIN)
{
$obdSeparator = ";";
}
else
{
$obdSeparator = ":";
}
// Create the array of open_basedir paths
$obdArray = explode($obdSeparator, $obd);
$inBaseDir = false;
// Iterate through open_basedir paths looking for a match
foreach ($obdArray as $test)
{
$test = JPath::clean($test);
if (strpos($path, $test) === 0)
{
$inBaseDir = true;
break;
}
}
if ($inBaseDir == false)
{
// Return false for JFolder::create because the path to be created is not in open_basedir
JError::raiseWarning('SOME_ERROR_CODE', __METHOD__ . ': ' . JText::_('JLIB_FILESYSTEM_ERROR_FOLDER_PATH'));
return false;
}
}
// First set umask
$origmask = @umask(0);
// Create the path
if (!$ret = @mkdir($path, $mode))
{
@umask($origmask);
JError::raiseWarning(
'SOME_ERROR_CODE', __METHOD__ . ': ' . JText::_('JLIB_FILESYSTEM_ERROR_COULD_NOT_CREATE_DIRECTORY').
' Path: ' . $path
);
return false;
}
// Reset umask
@umask($origmask);
}
return $ret;
}
/**
* Delete a folder.
*
* @param string $path The path to the folder to delete.
*
* @return boolean True on success.
*
* @since 11.1
*/
public static function delete($path)
{
@set_time_limit(ini_get('max_execution_time'));
// Sanity check
if (!$path)
{
// Bad programmer! Bad Bad programmer!
JError::raiseWarning(500, __METHOD__ . ': ' . JText::_('JLIB_FILESYSTEM_ERROR_DELETE_BASE_DIRECTORY'));
return false;
}
// Initialise variables.
$FTPOptions = JClientHelper::getCredentials('ftp');
try
{
// Check to make sure the path valid and clean
$path = JPath::clean($path);
}
catch (UnexpectedValueException $e)
{
throw new UnexpectedValueException($e);
}
// Is this really a folder?
if (!is_dir($path))
{
JError::raiseWarning(21, JText::sprintf('JLIB_FILESYSTEM_ERROR_PATH_IS_NOT_A_FOLDER', $path));
return false;
}
// Remove all the files in folder if they exist; disable all filtering
$files = self::files($path, '.', false, true, array(), array());
if (!empty($files))
{
jimport('joomla.filesystem.file');
if (JFile::delete($files) !== true)
{
// JFile::delete throws an error
return false;
}
}
// Remove sub-folders of folder; disable all filtering
$folders = self::folders($path, '.', false, true, array(), array());
foreach ($folders as $folder)
{
if (is_link($folder))
{
// Don't descend into linked directories, just delete the link.
jimport('joomla.filesystem.file');
if (JFile::delete($folder) !== true)
{
// JFile::delete throws an error
return false;
}
}
elseif (self::delete($folder) !== true)
{
// JFolder::delete throws an error
return false;
}
}
if ($FTPOptions['enabled'] == 1)
{
// Connect the FTP client
jimport('joomla.client.ftp');
$ftp = JFTP::getInstance($FTPOptions['host'], $FTPOptions['port'], null, $FTPOptions['user'], $FTPOptions['pass']);
}
// In case of restricted permissions we zap it one way or the other
// as long as the owner is either the webserver or the ftp.
if (@rmdir($path))
{
$ret = true;
}
elseif ($FTPOptions['enabled'] == 1)
{
// Translate path and delete
$path = JPath::clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $path), '/');
// FTP connector throws an error
$ret = $ftp->delete($path);
}
else
{
JError::raiseWarning('SOME_ERROR_CODE', JText::sprintf('JLIB_FILESYSTEM_ERROR_FOLDER_DELETE', $path));
$ret = false;
}
return $ret;
}
/**
* Moves a folder.
*
* @param string $src The path to the source folder.
* @param string $dest The path to the destination folder.
* @param string $path An optional base path to prefix to the file names.
* @param boolean $use_streams Optionally use streams.
*
* @return mixed Error message on false or boolean true on success.
*
* @since 11.1
*/
public static function move($src, $dest, $path = '', $use_streams = false)
{
// Initialise variables.
$FTPOptions = JClientHelper::getCredentials('ftp');
if ($path)
{
$src = JPath::clean($path . '/' . $src);
$dest = JPath::clean($path . '/' . $dest);
}
if (!self::exists($src))
{
return JText::_('JLIB_FILESYSTEM_ERROR_FIND_SOURCE_FOLDER');
}
if (self::exists($dest))
{
return JText::_('JLIB_FILESYSTEM_ERROR_FOLDER_EXISTS');
}
if ($use_streams)
{
$stream = JFactory::getStream();
if (!$stream->move($src, $dest))
{
return JText::sprintf('JLIB_FILESYSTEM_ERROR_FOLDER_RENAME', $stream->getError());
}
$ret = true;
}
else
{
if ($FTPOptions['enabled'] == 1)
{
// Connect the FTP client
jimport('joomla.client.ftp');
$ftp = JFTP::getInstance($FTPOptions['host'], $FTPOptions['port'], null, $FTPOptions['user'], $FTPOptions['pass']);
//Translate path for the FTP account
$src = JPath::clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $src), '/');
$dest = JPath::clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $dest), '/');
// Use FTP rename to simulate move
if (!$ftp->rename($src, $dest))
{
return JText::_('Rename failed');
}
$ret = true;
}
else
{
if (!@rename($src, $dest))
{
return JText::_('Rename failed');
}
$ret = true;
}
}
return $ret;
}
/**
* Wrapper for the standard file_exists function
*
* @param string $path Folder name relative to installation dir
*
* @return boolean True if path is a folder
*
* @since 11.1
*/
public static function exists($path)
{
return is_dir(JPath::clean($path));
}
/**
* Utility function to read the files in a folder.
*
* @param string $path The path of the folder to read.
* @param string $filter A filter for file names.
* @param mixed $recurse True to recursively search into sub-folders, or an integer to specify the maximum depth.
* @param boolean $full True to return the full path to the file.
* @param array $exclude Array with names of files which should not be shown in the result.
* @param array $excludefilter Array of filter to exclude
* @param boolean $naturalSort False for asort, true for natsort
*
* @return array Files in the given folder.
*
* @since 11.1
*/
public static function files($path, $filter = '.', $recurse = false, $full = false, $exclude = array('.svn', 'CVS', '.DS_Store', '__MACOSX'),
$excludefilter = array('^\..*', '.*~'), $naturalSort = false)
{
// Check to make sure the path valid and clean
$path = JPath::clean($path);
// Is the path a folder?
if (!is_dir($path))
{
JError::raiseWarning(21, JText::sprintf('JLIB_FILESYSTEM_ERROR_PATH_IS_NOT_A_FOLDER_FILES', $path));
return false;
}
// Compute the excludefilter string
if (count($excludefilter))
{
$excludefilter_string = '/(' . implode('|', $excludefilter) . ')/';
}
else
{
$excludefilter_string = '';
}
// Get the files
$arr = self::_items($path, $filter, $recurse, $full, $exclude, $excludefilter_string, true);
// Sort the files based on either natural or alpha method
if ($naturalSort)
{
natsort($arr);
}
else
{
asort($arr);
}
return array_values($arr);
}
/**
* Utility function to read the folders in a folder.
*
* @param string $path The path of the folder to read.
* @param string $filter A filter for folder names.
* @param mixed $recurse True to recursively search into sub-folders, or an integer to specify the maximum depth.
* @param boolean $full True to return the full path to the folders.
* @param array $exclude Array with names of folders which should not be shown in the result.
* @param array $excludefilter Array with regular expressions matching folders which should not be shown in the result.
*
* @return array Folders in the given folder.
*
* @since 11.1
*/
public static function folders($path, $filter = '.', $recurse = false, $full = false, $exclude = array('.svn', 'CVS', '.DS_Store', '__MACOSX'),
$excludefilter = array('^\..*'))
{
// Check to make sure the path valid and clean
$path = JPath::clean($path);
// Is the path a folder?
if (!is_dir($path))
{
JError::raiseWarning(21, JText::sprintf('JLIB_FILESYSTEM_ERROR_PATH_IS_NOT_A_FOLDER_FOLDER', $path));
return false;
}
// Compute the excludefilter string
if (count($excludefilter))
{
$excludefilter_string = '/(' . implode('|', $excludefilter) . ')/';
}
else
{
$excludefilter_string = '';
}
// Get the folders
$arr = self::_items($path, $filter, $recurse, $full, $exclude, $excludefilter_string, false);
// Sort the folders
asort($arr);
return array_values($arr);
}
/**
* Function to read the files/folders in a folder.
*
* @param string $path The path of the folder to read.
* @param string $filter A filter for file names.
* @param mixed $recurse True to recursively search into sub-folders, or an integer to specify the maximum depth.
* @param boolean $full True to return the full path to the file.
* @param array $exclude Array with names of files which should not be shown in the result.
* @param string $excludefilter_string Regexp of files to exclude
* @param boolean $findfiles True to read the files, false to read the folders
*
* @return array Files.
*
* @since 11.1
*/
protected static function _items($path, $filter, $recurse, $full, $exclude, $excludefilter_string, $findfiles)
{
@set_time_limit(ini_get('max_execution_time'));
// Initialise variables.
$arr = array();
// Read the source directory
if (!($handle = @opendir($path)))
{
return $arr;
}
while (($file = readdir($handle)) !== false)
{
if ($file != '.' && $file != '..' && !in_array($file, $exclude)
&& (empty($excludefilter_string) || !preg_match($excludefilter_string, $file)))
{
// Compute the fullpath
$fullpath = $path . DIRECTORY_SEPARATOR . $file;
// Compute the isDir flag
$isDir = is_dir($fullpath);
if (($isDir xor $findfiles) && preg_match("/$filter/", $file))
{
// (fullpath is dir and folders are searched or fullpath is not dir and files are searched) and file matches the filter
if ($full)
{
// Full path is requested
$arr[] = $fullpath;
}
else
{
// Filename is requested
$arr[] = $file;
}
}
if ($isDir && $recurse)
{
// Search recursively
if (is_integer($recurse))
{
// Until depth 0 is reached
$arr = array_merge($arr, self::_items($fullpath, $filter, $recurse - 1, $full, $exclude, $excludefilter_string, $findfiles));
}
else
{
$arr = array_merge($arr, self::_items($fullpath, $filter, $recurse, $full, $exclude, $excludefilter_string, $findfiles));
}
}
}
}
closedir($handle);
return $arr;
}
/**
* Lists folder in format suitable for tree display.
*
* @param string $path The path of the folder to read.
* @param string $filter A filter for folder names.
* @param integer $maxLevel The maximum number of levels to recursively read, defaults to three.
* @param integer $level The current level, optional.
* @param integer $parent Unique identifier of the parent folder, if any.
*
* @return array Folders in the given folder.
*
* @since 11.1
*/
public static function listFolderTree($path, $filter, $maxLevel = 3, $level = 0, $parent = 0)
{
$dirs = array();
if ($level == 0)
{
$GLOBALS['_JFolder_folder_tree_index'] = 0;
}
if ($level < $maxLevel)
{
$folders = self::folders($path, $filter);
// First path, index foldernames
foreach ($folders as $name)
{
$id = ++$GLOBALS['_JFolder_folder_tree_index'];
$fullName = JPath::clean($path . '/' . $name);
$dirs[] = array('id' => $id, 'parent' => $parent, 'name' => $name, 'fullname' => $fullName,
'relname' => str_replace(JPATH_ROOT, '', $fullName));
$dirs2 = self::listFolderTree($fullName, $filter, $maxLevel, $level + 1, $id);
$dirs = array_merge($dirs, $dirs2);
}
}
return $dirs;
}
/**
* Makes path name safe to use.
*
* @param string $path The full path to sanitise.
*
* @return string The sanitised string.
*
* @since 11.1
*/
public static function makeSafe($path)
{
$regex = array('#[^A-Za-z0-9:_\\\/-]#');
return preg_replace($regex, '', $path);
}
}
PK 3?\'&1 1 file.phpnu W+A copy($src, $dest))
{
JError::raiseWarning(21, JText::sprintf('JLIB_FILESYSTEM_ERROR_JFILE_STREAMS', $src, $dest, $stream->getError()));
return false;
}
return true;
}
else
{
// Initialise variables.
$FTPOptions = JClientHelper::getCredentials('ftp');
if ($FTPOptions['enabled'] == 1)
{
// Connect the FTP client
jimport('joomla.client.ftp');
$ftp = JFTP::getInstance($FTPOptions['host'], $FTPOptions['port'], null, $FTPOptions['user'], $FTPOptions['pass']);
// If the parent folder doesn't exist we must create it
if (!file_exists(dirname($dest)))
{
jimport('joomla.filesystem.folder');
JFolder::create(dirname($dest));
}
// Translate the destination path for the FTP account
$dest = JPath::clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $dest), '/');
if (!$ftp->store($src, $dest))
{
// FTP connector throws an error
return false;
}
$ret = true;
}
else
{
if (!@ copy($src, $dest))
{
JError::raiseWarning(21, JText::_('JLIB_FILESYSTEM_ERROR_COPY_FAILED'));
return false;
}
$ret = true;
}
return $ret;
}
}
/**
* Delete a file or array of files
*
* @param mixed $file The file name or an array of file names
*
* @return boolean True on success
*
* @since 11.1
*/
public static function delete($file)
{
// Initialise variables.
jimport('joomla.client.helper');
$FTPOptions = JClientHelper::getCredentials('ftp');
if (is_array($file))
{
$files = $file;
}
else
{
$files[] = $file;
}
// Do NOT use ftp if it is not enabled
if ($FTPOptions['enabled'] == 1)
{
// Connect the FTP client
jimport('joomla.client.ftp');
$ftp = JFTP::getInstance($FTPOptions['host'], $FTPOptions['port'], null, $FTPOptions['user'], $FTPOptions['pass']);
}
foreach ($files as $file)
{
$file = JPath::clean($file);
if (!is_file($file))
{
continue;
}
// Try making the file writable first. If it's read-only, it can't be deleted
// on Windows, even if the parent folder is writable
@chmod($file, 0777);
// In case of restricted permissions we zap it one way or the other
// as long as the owner is either the webserver or the ftp
if (@unlink($file))
{
// Do nothing
}
elseif ($FTPOptions['enabled'] == 1)
{
$file = JPath::clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $file), '/');
if (!$ftp->delete($file))
{
// FTP connector throws an error
return false;
}
}
else
{
$filename = basename($file);
JError::raiseWarning('SOME_ERROR_CODE', JText::sprintf('JLIB_FILESYSTEM_DELETE_FAILED', $filename));
return false;
}
}
return true;
}
/**
* Moves a file
*
* @param string $src The path to the source file
* @param string $dest The path to the destination file
* @param string $path An optional base path to prefix to the file names
* @param boolean $use_streams True to use streams
*
* @return boolean True on success
*
* @since 11.1
*/
public static function move($src, $dest, $path = '', $use_streams = false)
{
if ($path)
{
$src = JPath::clean($path . '/' . $src);
$dest = JPath::clean($path . '/' . $dest);
}
// Check src path
if (!is_readable($src))
{
return JText::_('JLIB_FILESYSTEM_CANNOT_FIND_SOURCE_FILE');
}
if ($use_streams)
{
$stream = JFactory::getStream();
if (!$stream->move($src, $dest))
{
JError::raiseWarning(21, JText::sprintf('JLIB_FILESYSTEM_ERROR_JFILE_MOVE_STREAMS', $stream->getError()));
return false;
}
return true;
}
else
{
// Initialise variables.
jimport('joomla.client.helper');
$FTPOptions = JClientHelper::getCredentials('ftp');
if ($FTPOptions['enabled'] == 1)
{
// Connect the FTP client
jimport('joomla.client.ftp');
$ftp = JFTP::getInstance($FTPOptions['host'], $FTPOptions['port'], null, $FTPOptions['user'], $FTPOptions['pass']);
// Translate path for the FTP account
$src = JPath::clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $src), '/');
$dest = JPath::clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $dest), '/');
// Use FTP rename to simulate move
if (!$ftp->rename($src, $dest))
{
JError::raiseWarning(21, JText::_('JLIB_FILESYSTEM_ERROR_RENAME_FILE'));
return false;
}
}
else
{
if (!@ rename($src, $dest))
{
JError::raiseWarning(21, JText::_('JLIB_FILESYSTEM_ERROR_RENAME_FILE'));
return false;
}
}
return true;
}
}
/**
* Read the contents of a file
*
* @param string $filename The full file path
* @param boolean $incpath Use include path
* @param integer $amount Amount of file to read
* @param integer $chunksize Size of chunks to read
* @param integer $offset Offset of the file
*
* @return mixed Returns file contents or boolean False if failed
*
* @since 11.1
*/
public static function read($filename, $incpath = false, $amount = 0, $chunksize = 8192, $offset = 0)
{
// Initialise variables.
$data = null;
if ($amount && $chunksize > $amount)
{
$chunksize = $amount;
}
if (false === $fh = fopen($filename, 'rb', $incpath))
{
JError::raiseWarning(21, JText::sprintf('JLIB_FILESYSTEM_ERROR_READ_UNABLE_TO_OPEN_FILE', $filename));
return false;
}
clearstatcache();
if ($offset)
{
fseek($fh, $offset);
}
if ($fsize = @ filesize($filename))
{
if ($amount && $fsize > $amount)
{
$data = fread($fh, $amount);
}
else
{
$data = fread($fh, $fsize);
}
}
else
{
$data = '';
// While it's:
// 1: Not the end of the file AND
// 2a: No Max Amount set OR
// 2b: The length of the data is less than the max amount we want
while (!feof($fh) && (!$amount || strlen($data) < $amount))
{
$data .= fread($fh, $chunksize);
}
}
fclose($fh);
return $data;
}
/**
* Write contents to a file
*
* @param string $file The full file path
* @param string &$buffer The buffer to write
* @param boolean $use_streams Use streams
*
* @return boolean True on success
*
* @since 11.1
*/
public static function write($file, &$buffer, $use_streams = false)
{
@set_time_limit(ini_get('max_execution_time'));
// If the destination directory doesn't exist we need to create it
if (!file_exists(dirname($file)))
{
jimport('joomla.filesystem.folder');
JFolder::create(dirname($file));
}
if ($use_streams)
{
$stream = JFactory::getStream();
// Beef up the chunk size to a meg
$stream->set('chunksize', (1024 * 1024 * 1024));
if (!$stream->writeFile($file, $buffer))
{
JError::raiseWarning(21, JText::sprintf('JLIB_FILESYSTEM_ERROR_WRITE_STREAMS', $file, $stream->getError()));
return false;
}
return true;
}
else
{
// Initialise variables.
$FTPOptions = JClientHelper::getCredentials('ftp');
if ($FTPOptions['enabled'] == 1)
{
// Connect the FTP client
jimport('joomla.client.ftp');
$ftp = JFTP::getInstance($FTPOptions['host'], $FTPOptions['port'], null, $FTPOptions['user'], $FTPOptions['pass']);
// Translate path for the FTP account and use FTP write buffer to file
$file = JPath::clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $file), '/');
$ret = $ftp->write($file, $buffer);
}
else
{
$file = JPath::clean($file);
$ret = is_int(file_put_contents($file, $buffer)) ? true : false;
}
return $ret;
}
}
/**
* Moves an uploaded file to a destination folder
*
* @param string $src The name of the php (temporary) uploaded file
* @param string $dest The path (including filename) to move the uploaded file to
* @param boolean $use_streams True to use streams
*
* @return boolean True on success
*
* @since 11.1
*/
public static function upload($src, $dest, $use_streams = false)
{
// Ensure that the path is valid and clean
$dest = JPath::clean($dest);
// Create the destination directory if it does not exist
$baseDir = dirname($dest);
if (!file_exists($baseDir))
{
jimport('joomla.filesystem.folder');
JFolder::create($baseDir);
}
if ($use_streams)
{
$stream = JFactory::getStream();
if (!$stream->upload($src, $dest))
{
JError::raiseWarning(21, JText::sprintf('JLIB_FILESYSTEM_ERROR_UPLOAD', $stream->getError()));
return false;
}
return true;
}
else
{
// Initialise variables.
$FTPOptions = JClientHelper::getCredentials('ftp');
$ret = false;
if ($FTPOptions['enabled'] == 1)
{
// Connect the FTP client
jimport('joomla.client.ftp');
$ftp = JFTP::getInstance($FTPOptions['host'], $FTPOptions['port'], null, $FTPOptions['user'], $FTPOptions['pass']);
// Translate path for the FTP account
$dest = JPath::clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $dest), '/');
// Copy the file to the destination directory
if (is_uploaded_file($src) && $ftp->store($src, $dest))
{
unlink($src);
$ret = true;
}
else
{
JError::raiseWarning(21, JText::_('JLIB_FILESYSTEM_ERROR_WARNFS_ERR02'));
}
}
else
{
if (is_writeable($baseDir) && move_uploaded_file($src, $dest))
{
// Short circuit to prevent file permission errors
if (JPath::setPermissions($dest))
{
$ret = true;
}
else
{
JError::raiseWarning(21, JText::_('JLIB_FILESYSTEM_ERROR_WARNFS_ERR01'));
}
}
else
{
JError::raiseWarning(21, JText::_('JLIB_FILESYSTEM_ERROR_WARNFS_ERR02'));
}
}
return $ret;
}
}
/**
* Wrapper for the standard file_exists function
*
* @param string $file File path
*
* @return boolean True if path is a file
*
* @since 11.1
*/
public static function exists($file)
{
return is_file(JPath::clean($file));
}
/**
* Returns the name, without any path.
*
* @param string $file File path
*
* @return string filename
*
* @since 11.1
*/
public static function getName($file)
{
// Convert back slashes to forward slashes
$file = str_replace('\\', '/', $file);
$slash = strrpos($file, '/');
if ($slash !== false)
{
return substr($file, $slash + 1);
}
else
{
return $file;
}
}
}
PK 3?\V
index.htmlnu W+A
PK 3?\W( path.phpnu W+A
Order allow,deny
Deny from all
PK 3?\~ ~
stream.phpnu W+A writeprefix = $writeprefix;
$this->readprefix = $readprefix;
$this->_contextOptions = $context;
$this->_buildContext();
}
/**
* Destructor
*
* @since 11.1
*/
public function __destruct()
{
// Attempt to close on destruction if there is a file handle
if ($this->_fh)
{
@$this->close();
}
}
/**
* Generic File Operations
*
* Open a stream with some lazy loading smarts
*
* @param string $filename Filename
* @param string $mode Mode string to use
* @param boolean $use_include_path Use the PHP include path
* @param resource $context Context to use when opening
* @param boolean $use_prefix Use a prefix to open the file
* @param boolean $relative Filename is a relative path (if false, strips JPATH_ROOT to make it relative)
* @param boolean $detectprocessingmode Detect the processing method for the file and use the appropriate function
* to handle output automatically
*
* @return boolean
*
* @since 11.1
*/
public function open($filename, $mode = 'r', $use_include_path = false, $context = null,
$use_prefix = false, $relative = false, $detectprocessingmode = false)
{
$filename = $this->_getFilename($filename, $mode, $use_prefix, $relative);
if (!$filename)
{
$this->setError(JText::_('JLIB_FILESYSTEM_ERROR_STREAMS_FILENAME'));
return false;
}
$this->filename = $filename;
$this->_openmode = $mode;
$url = parse_url($filename);
$retval = false;
if (isset($url['scheme']))
{
// If we're dealing with a Joomla! stream, load it
if (JFilesystemHelper::isJoomlaStream($url['scheme']))
{
require_once dirname(__FILE__) . '/streams/' . $url['scheme'] . '.php';
}
// We have a scheme! force the method to be f
$this->processingmethod = 'f';
}
elseif ($detectprocessingmode)
{
$ext = strtolower(JFile::getExt($this->filename));
switch ($ext)
{
case 'tgz':
case 'gz':
case 'gzip':
$this->processingmethod = 'gz';
break;
case 'tbz2':
case 'bz2':
case 'bzip2':
$this->processingmethod = 'bz';
break;
default:
$this->processingmethod = 'f';
break;
}
}
// Capture PHP errors
$php_errormsg = 'Error Unknown whilst opening a file';
$track_errors = ini_get('track_errors');
ini_set('track_errors', true);
// Decide which context to use:
switch ($this->processingmethod)
{
// gzip doesn't support contexts or streams
case 'gz':
$this->_fh = gzopen($filename, $mode, $use_include_path);
break;
// bzip2 is much like gzip except it doesn't use the include path
case 'bz':
$this->_fh = bzopen($filename, $mode);
break;
// fopen can handle streams
case 'f':
default:
// One supplied at open; overrides everything
if ($context)
{
$this->_fh = fopen($filename, $mode, $use_include_path, $context);
}
// One provided at initialisation
elseif ($this->_context)
{
$this->_fh = fopen($filename, $mode, $use_include_path, $this->_context);
}
// No context; all defaults
else
{
$this->_fh = fopen($filename, $mode, $use_include_path);
}
break;
}
if (!$this->_fh)
{
$this->setError($php_errormsg);
}
else
{
$retval = true;
}
// Restore error tracking to what it was before
ini_set('track_errors', $track_errors);
// Return the result
return $retval;
}
/**
* Attempt to close a file handle
*
* Will return false if it failed and true on success
* If the file is not open the system will return true, this function destroys the file handle as well
*
* @return boolean
*
* @since 11.1
*/
public function close()
{
if (!$this->_fh)
{
$this->setError(JText::_('JLIB_FILESYSTEM_ERROR_STREAMS_FILE_NOT_OPEN'));
return true;
}
$retval = false;
// Capture PHP errors
$php_errormsg = 'Error Unknown';
$track_errors = ini_get('track_errors');
ini_set('track_errors', true);
switch ($this->processingmethod)
{
case 'gz':
$res = gzclose($this->_fh);
break;
case 'bz':
$res = bzclose($this->_fh);
break;
case 'f':
default:
$res = fclose($this->_fh);
break;
}
if (!$res)
{
$this->setError($php_errormsg);
}
else
{
// reset this
$this->_fh = null;
$retval = true;
}
// If we wrote, chmod the file after it's closed
if ($this->_openmode[0] == 'w')
{
$this->chmod();
}
// Restore error tracking to what it was before
ini_set('track_errors', $track_errors);
// Return the result
return $retval;
}
/**
* Work out if we're at the end of the file for a stream
*
* @return boolean
*
* @since 11.1
*/
public function eof()
{
if (!$this->_fh)
{
$this->setError(JText::_('JLIB_FILESYSTEM_ERROR_STREAMS_FILE_NOT_OPEN'));
return false;
}
// Capture PHP errors
$php_errormsg = '';
$track_errors = ini_get('track_errors');
ini_set('track_errors', true);
switch ($this->processingmethod)
{
case 'gz':
$res = gzeof($this->_fh);
break;
case 'bz':
case 'f':
default:
$res = feof($this->_fh);
break;
}
if ($php_errormsg)
{
$this->setError($php_errormsg);
}
// Restore error tracking to what it was before
ini_set('track_errors', $track_errors);
// Return the result
return $res;
}
/**
* Retrieve the file size of the path
*
* @return mixed
*
* @since 11.1
*/
public function filesize()
{
if (!$this->filename)
{
$this->setError(JText::_('JLIB_FILESYSTEM_ERROR_STREAMS_FILE_NOT_OPEN'));
return false;
}
$retval = false;
// Capture PHP errors
$php_errormsg = '';
$track_errors = ini_get('track_errors');
ini_set('track_errors', true);
$res = @filesize($this->filename);
if (!$res)
{
$tmp_error = '';
if ($php_errormsg)
{
// Something went wrong.
// Store the error in case we need it.
$tmp_error = $php_errormsg;
}
$res = JFilesystemHelper::remotefsize($this->filename);
if (!$res)
{
if ($tmp_error)
{
// Use the php_errormsg from before
$this->setError($tmp_error);
}
else
{
// Error but nothing from php? How strange! Create our own
$this->setError(JText::_('JLIB_FILESYSTEM_ERROR_STREAMS_FILE_SIZE'));
}
}
else
{
$this->_filesize = $res;
$retval = $res;
}
}
else
{
$this->_filesize = $res;
$retval = $res;
}
// Restore error tracking to what it was before.
ini_set('track_errors', $track_errors);
// return the result
return $retval;
}
/**
* Get a line from the stream source.
*
* @param integer $length The number of bytes (optional) to read.
*
* @return mixed
*
* @since 11.1
*/
public function gets($length = 0)
{
if (!$this->_fh)
{
$this->setError(JText::_('JLIB_FILESYSTEM_ERROR_STREAMS_FILE_NOT_OPEN'));
return false;
}
$retval = false;
// Capture PHP errors
$php_errormsg = 'Error Unknown';
$track_errors = ini_get('track_errors');
ini_set('track_errors', true);
switch ($this->processingmethod)
{
case 'gz':
$res = $length ? gzgets($this->_fh, $length) : gzgets($this->_fh);
break;
case 'bz':
case 'f':
default:
$res = $length ? fgets($this->_fh, $length) : fgets($this->_fh);
break;
}
if (!$res)
{
$this->setError($php_errormsg);
}
else
{
$retval = $res;
}
// Restore error tracking to what it was before
ini_set('track_errors', $track_errors);
// return the result
return $retval;
}
/**
* Read a file
*
* Handles user space streams appropriately otherwise any read will return 8192
*
* @param integer $length Length of data to read
*
* @return mixed
*
* @see http://php.net/manual/en/function.fread.php
* @since 11.1
*/
public function read($length = 0)
{
if (!$this->_filesize && !$length)
{
// Get the filesize
$this->filesize();
if (!$this->_filesize)
{
// Set it to the biggest and then wait until eof
$length = -1;
}
else
{
$length = $this->_filesize;
}
}
if (!$this->_fh)
{
$this->setError(JText::_('JLIB_FILESYSTEM_ERROR_STREAMS_FILE_NOT_OPEN'));
return false;
}
$retval = false;
// Capture PHP errors
$php_errormsg = 'Error Unknown';
$track_errors = ini_get('track_errors');
ini_set('track_errors', true);
$remaining = $length;
do
{
// Do chunked reads where relevant
switch ($this->processingmethod)
{
case 'bz':
$res = ($remaining > 0) ? bzread($this->_fh, $remaining) : bzread($this->_fh, $this->chunksize);
break;
case 'gz':
$res = ($remaining > 0) ? gzread($this->_fh, $remaining) : gzread($this->_fh, $this->chunksize);
break;
case 'f':
default:
$res = ($remaining > 0) ? fread($this->_fh, $remaining) : fread($this->_fh, $this->chunksize);
break;
}
if (!$res)
{
$this->setError($php_errormsg);
$remaining = 0; // jump from the loop
}
else
{
if (!$retval)
{
$retval = '';
}
$retval .= $res;
if (!$this->eof())
{
$len = strlen($res);
$remaining -= $len;
}
else
{
// If it's the end of the file then we've nothing left to read; reset remaining and len
$remaining = 0;
$length = strlen($retval);
}
}
}
while ($remaining || !$length);
// Restore error tracking to what it was before
ini_set('track_errors', $track_errors);
// Return the result
return $retval;
}
/**
* Seek the file
*
* Note: the return value is different to that of fseek
*
* @param integer $offset Offset to use when seeking.
* @param integer $whence Seek mode to use.
*
* @return boolean True on success, false on failure
*
* @see http://php.net/manual/en/function.fseek.php
* @since 11.1
*/
public function seek($offset, $whence = SEEK_SET)
{
if (!$this->_fh)
{
$this->setError(JText::_('JLIB_FILESYSTEM_ERROR_STREAMS_FILE_NOT_OPEN'));
return false;
}
$retval = false;
// Capture PHP errors
$php_errormsg = '';
$track_errors = ini_get('track_errors');
ini_set('track_errors', true);
switch ($this->processingmethod)
{
case 'gz':
$res = gzseek($this->_fh, $offset, $whence);
break;
case 'bz':
case 'f':
default:
$res = fseek($this->_fh, $offset, $whence);
break;
}
// Seek, interestingly, returns 0 on success or -1 on failure.
if ($res == -1)
{
$this->setError($php_errormsg);
}
else
{
$retval = true;
}
// Restore error tracking to what it was before
ini_set('track_errors', $track_errors);
// Return the result
return $retval;
}
/**
* Returns the current position of the file read/write pointer.
*
* @return mixed
*
* @since 11.1
*/
public function tell()
{
if (!$this->_fh)
{
$this->setError(JText::_('JLIB_FILESYSTEM_ERROR_STREAMS_FILE_NOT_OPEN'));
return false;
}
$res = false;
// Capture PHP errors
$php_errormsg = '';
$track_errors = ini_get('track_errors');
ini_set('track_errors', true);
switch ($this->processingmethod)
{
case 'gz':
$res = gztell($this->_fh);
break;
case 'bz':
case 'f':
default:
$res = ftell($this->_fh);
break;
}
// May return 0 so check if it's really false
if ($res === false)
{
$this->setError($php_errormsg);
}
// Restore error tracking to what it was before
ini_set('track_errors', $track_errors);
// Return the result
return $res;
}
/**
* File write
*
* Whilst this function accepts a reference, the underlying fwrite
* will do a copy! This will roughly double the memory allocation for
* any write you do. Specifying chunked will get around this by only
* writing in specific chunk sizes. This defaults to 8192 which is a
* sane number to use most of the time (change the default with
* JStream::set('chunksize', newsize);)
* Note: This doesn't support gzip/bzip2 writing like reading does
*
* @param string &$string Reference to the string to write.
* @param integer $length Length of the string to write.
* @param integer $chunk Size of chunks to write in.
*
* @return boolean
*
* @see http://php.net/manual/en/function.fwrite.php
* @since 11.1
*/
public function write(&$string, $length = 0, $chunk = 0)
{
if (!$this->_fh)
{
$this->setError(JText::_('JLIB_FILESYSTEM_ERROR_STREAMS_FILE_NOT_OPEN'));
return false;
}
// If the length isn't set, set it to the length of the string.
if (!$length)
{
$length = strlen($string);
}
// If the chunk isn't set, set it to the default.
if (!$chunk)
{
$chunk = $this->chunksize;
}
$retval = true;
// Capture PHP errors
$php_errormsg = '';
$track_errors = ini_get('track_errors');
ini_set('track_errors', true);
$remaining = $length;
do
{
// If the amount remaining is greater than the chunk size, then use the chunk
$amount = ($remaining > $chunk) ? $chunk : $remaining;
$res = fwrite($this->_fh, $string, $amount);
// Returns false on error or the number of bytes written
if ($res === false)
{
// Returned error
$this->setError($php_errormsg);
$retval = false;
$remaining = 0;
}
elseif ($res === 0)
{
// Wrote nothing?
$remaining = 0;
$this->setError(JText::_('JLIB_FILESYSTEM_ERROR_NO_DATA_WRITTEN'));
}
else
{
// Wrote something
$remaining -= $res;
}
}
while ($remaining);
// Restore error tracking to what it was before.
ini_set('track_errors', $track_errors);
// Return the result
return $retval;
}
/**
* Chmod wrapper
*
* @param string $filename File name.
* @param mixed $mode Mode to use.
*
* @return boolean
*
* @since 11.1
*/
public function chmod($filename = '', $mode = 0)
{
if (!$filename)
{
if (!isset($this->filename) || !$this->filename)
{
$this->setError(JText::_('JLIB_FILESYSTEM_ERROR_STREAMS_FILENAME'));
return false;
}
$filename = $this->filename;
}
// If no mode is set use the default
if (!$mode)
{
$mode = $this->filemode;
}
$retval = false;
// Capture PHP errors
$php_errormsg = '';
$track_errors = ini_get('track_errors');
ini_set('track_errors', true);
$sch = parse_url($filename, PHP_URL_SCHEME);
// Scheme specific options; ftp's chmod support is fun.
switch ($sch)
{
case 'ftp':
case 'ftps':
$res = JFilesystemHelper::ftpChmod($filename, $mode);
break;
default:
$res = chmod($filename, $mode);
break;
}
// Seek, interestingly, returns 0 on success or -1 on failure
if (!$res)
{
$this->setError($php_errormsg);
}
else
{
$retval = true;
}
// Restore error tracking to what it was before.
ini_set('track_errors', $track_errors);
// Return the result
return $retval;
}
/**
* Get the stream metadata
*
* @return array header/metadata
*
* @see http://php.net/manual/en/function.stream-get-meta-data.php
* @since 11.1
*/
public function get_meta_data()
{
if (!$this->_fh)
{
$this->setError(JText::_('JLIB_FILESYSTEM_ERROR_STREAMS_FILE_NOT_OPEN'));
return false;
}
return stream_get_meta_data($this->_fh);
}
/**
* Stream contexts
* Builds the context from the array
*
* @return mixed
*
* @since 11.1
*/
public function _buildContext()
{
// According to the manual this always works!
if (count($this->_contextOptions))
{
$this->_context = @stream_context_create($this->_contextOptions);
}
else
{
$this->_context = null;
}
}
/**
* Updates the context to the array
*
* Format is the same as the options for stream_context_create
*
* @param array $context Options to create the context with
*
* @return void
*
* @see http://php.net/stream_context_create
* @since 11.1
*/
public function setContextOptions($context)
{
$this->_contextOptions = $context;
$this->_buildContext();
}
/**
* Adds a particular options to the context
*
* @param string $wrapper The wrapper to use
* @param string $name The option to set
* @param string $value The value of the option
*
* @return void
*
* @see http://php.net/stream_context_create Stream Context Creation
* @see http://php.net/manual/en/context.php Context Options for various streams
* @since 11.1
*/
public function addContextEntry($wrapper, $name, $value)
{
$this->_contextOptions[$wrapper][$name] = $value;
$this->_buildContext();
}
/**
* Deletes a particular setting from a context
*
* @param string $wrapper The wrapper to use
* @param string $name The option to unset
*
* @return void
*
* @see http://php.net/stream_context_create
* @since 11.1
*/
public function deleteContextEntry($wrapper, $name)
{
// Check whether the wrapper is set
if (isset($this->_contextOptions[$wrapper]))
{
// Check that entry is set for that wrapper
if (isset($this->_contextOptions[$wrapper][$name]))
{
// Unset the item
unset($this->_contextOptions[$wrapper][$name]);
// Check that there are still items there
if (!count($this->_contextOptions[$wrapper]))
{
// Clean up an empty wrapper context option
unset($this->_contextOptions[$wrapper]);
}
}
}
// Rebuild the context and apply it to the stream
$this->_buildContext();
}
/**
* Applies the current context to the stream
*
* Use this to change the values of the context after you've opened a stream
*
* @return mixed
*
* @since 11.1
*/
public function applyContextToStream()
{
$retval = false;
if ($this->_fh)
{
// Capture PHP errors
$php_errormsg = 'Unknown error setting context option';
$track_errors = ini_get('track_errors');
ini_set('track_errors', true);
$retval = @stream_context_set_option($this->_fh, $this->_contextOptions);
if (!$retval)
{
$this->setError($php_errormsg);
}
// restore error tracking to what it was before
ini_set('track_errors', $track_errors);
}
return $retval;
}
/**
* Stream filters
* Append a filter to the chain
*
* @param string $filtername The key name of the filter.
* @param integer $read_write Optional. Defaults to STREAM_FILTER_READ.
* @param array $params An array of params for the stream_filter_append call.
*
* @return mixed
*
* @see http://php.net/manual/en/function.stream-filter-append.php
* @since 11.1
*/
public function appendFilter($filtername, $read_write = STREAM_FILTER_READ, $params = array())
{
$res = false;
if ($this->_fh)
{
// Capture PHP errors
$php_errormsg = '';
$track_errors = ini_get('track_errors');
ini_set('track_errors', true);
$res = @stream_filter_append($this->_fh, $filtername, $read_write, $params);
if (!$res && $php_errormsg)
{
$this->setError($php_errormsg);
}
else
{
$this->filters[] = &$res;
}
// Restore error tracking to what it was before.
ini_set('track_errors', $track_errors);
}
return $res;
}
/**
* Prepend a filter to the chain
*
* @param string $filtername The key name of the filter.
* @param integer $read_write Optional. Defaults to STREAM_FILTER_READ.
* @param array $params An array of params for the stream_filter_prepend call.
*
* @return mixed
*
* @see http://php.net/manual/en/function.stream-filter-prepend.php
* @since 11.1
*/
public function prependFilter($filtername, $read_write = STREAM_FILTER_READ, $params = array())
{
$res = false;
if ($this->_fh)
{
// Capture PHP errors
$php_errormsg = '';
$track_errors = ini_get('track_errors');
ini_set('track_errors', true);
$res = @stream_filter_prepend($this->_fh, $filtername, $read_write, $params);
if (!$res && $php_errormsg)
{
$this->setError($php_errormsg); // set the error msg
}
else
{
array_unshift($res, '');
$res[0] = &$this->filters;
}
// Restore error tracking to what it was before.
ini_set('track_errors', $track_errors);
}
return $res;
}
/**
* Remove a filter, either by resource (handed out from the append or prepend function)
* or via getting the filter list)
*
* @param resource &$resource The resource.
* @param boolean $byindex The index of the filter.
*
* @return boolean Result of operation
*
* @since 11.1
*/
public function removeFilter(&$resource, $byindex = false)
{
$res = false;
// Capture PHP errors
$php_errormsg = '';
$track_errors = ini_get('track_errors');
ini_set('track_errors', true);
if ($byindex)
{
$res = stream_filter_remove($this->filters[$resource]);
}
else
{
$res = stream_filter_remove($resource);
}
if ($res && $php_errormsg)
{
$this->setError($php_errormsg);
}
// Restore error tracking to what it was before.
ini_set('track_errors', $track_errors);
return $res;
}
/**
* Copy a file from src to dest
*
* @param string $src The file path to copy from.
* @param string $dest The file path to copy to.
* @param resource $context A valid context resource (optional) created with stream_context_create.
* @param boolean $use_prefix Controls the use of a prefix (optional).
* @param boolean $relative Determines if the filename given is relative. Relative paths do not have JPATH_ROOT stripped.
*
* @return mixed
*
* @since 11.1
*/
public function copy($src, $dest, $context = null, $use_prefix = true, $relative = false)
{
$res = false;
// Capture PHP errors
$php_errormsg = '';
$track_errors = ini_get('track_errors');
ini_set('track_errors', true);
$chmodDest = $this->_getFilename($dest, 'w', $use_prefix, $relative);
$exists = file_exists($dest);
$context_support = version_compare(PHP_VERSION, '5.3', '>='); // 5.3 provides context support
if ($exists && !$context_support)
{
// The file exists and there is no context support.
// This could cause a failure as we may need to overwrite the file.
// So we write our own copy function that will work with a stream
// context; php 5.3 will fix this for us (yay!).
// Note: Since open processes the filename for us we won't worry about
// calling _getFilename
$res = $this->open($src);
if ($res)
{
$reader = $this->_fh;
$res = $this->open($dest, 'w');
if ($res)
{
$res = stream_copy_to_stream($reader, $this->_fh);
$tmperror = $php_errormsg; // save this in case fclose throws an error
@fclose($reader);
$php_errormsg = $tmperror; // restore after fclose
}
else
{
@fclose($reader); // close the reader off
$php_errormsg = JText::sprintf('JLIB_FILESYSTEM_ERROR_STREAMS_FAILED_TO_OPEN_WRITER', $this->getError());
}
}
else
{
if (!$php_errormsg)
{
$php_errormsg = JText::sprintf('JLIB_FILESYSTEM_ERROR_STREAMS_FAILED_TO_OPEN_READER', $this->getError());
}
}
}
else
{
// Since we're going to open the file directly we need to get the filename.
// We need to use the same prefix so force everything to write.
$src = $this->_getFilename($src, 'w', $use_prefix, $relative);
$dest = $this->_getFilename($dest, 'w', $use_prefix, $relative);
if ($context_support && $context)
{
// Use the provided context
$res = @copy($src, $dest, $context);
}
elseif ($context_support && $this->_context)
{
// Use the objects context
$res = @copy($src, $dest, $this->_context);
}
else
{
// Don't use any context
$res = @copy($src, $dest);
}
}
if (!$res && $php_errormsg)
{
$this->setError($php_errormsg);
}
else
{
$this->chmod($chmodDest);
}
// Restore error tracking to what it was before
ini_set('track_errors', $track_errors);
return $res;
}
/**
* Moves a file
*
* @param string $src The file path to move from.
* @param string $dest The file path to move to.
* @param resource $context A valid context resource (optional) created with stream_context_create.
* @param boolean $use_prefix Controls the use of a prefix (optional).
* @param boolean $relative Determines if the filename given is relative. Relative paths do not have JPATH_ROOT stripped.
*
* @return mixed
*
* @since 11.1
*/
public function move($src, $dest, $context = null, $use_prefix = true, $relative = false)
{
$res = false;
// Capture PHP errors
$php_errormsg = '';
$track_errors = ini_get('track_errors');
ini_set('track_errors', true);
$src = $this->_getFilename($src, 'w', $use_prefix, $relative);
$dest = $this->_getFilename($dest, 'w', $use_prefix, $relative);
if ($context)
{
// Use the provided context
$res = @rename($src, $dest, $context);
}
elseif ($this->_context)
{
// Use the object's context
$res = @rename($src, $dest, $this->_context);
}
else
{
// Don't use any context
$res = @rename($src, $dest);
}
if (!$res && $php_errormsg)
{
$this->setError($php_errormsg());
}
$this->chmod($dest);
// Restore error tracking to what it was before
ini_set('track_errors', $track_errors);
return $res;
}
/**
* Delete a file
*
* @param string $filename The file path to delete.
* @param resource $context A valid context resource (optional) created with stream_context_create.
* @param boolean $use_prefix Controls the use of a prefix (optional).
* @param boolean $relative Determines if the filename given is relative. Relative paths do not have JPATH_ROOT stripped.
*
* @return mixed
*
* @since 11.1
*/
public function delete($filename, $context = null, $use_prefix = true, $relative = false)
{
$res = false;
// Capture PHP errors
$php_errormsg = '';
$track_errors = ini_get('track_errors');
ini_set('track_errors', true);
$filename = $this->_getFilename($filename, 'w', $use_prefix, $relative);
if ($context)
{
// Use the provided context
$res = @unlink($filename, $context);
}
elseif ($this->_context)
{
// Use the object's context
$res = @unlink($filename, $this->_context);
}
else
{
// Don't use any context
$res = @unlink($filename);
}
if (!$res && $php_errormsg)
{
$this->setError($php_errormsg());
}
// Restore error tracking to what it was before.
ini_set('track_errors', $track_errors);
return $res;
}
/**
* Upload a file
*
* @param string $src The file path to copy from (usually a temp folder).
* @param string $dest The file path to copy to.
* @param resource $context A valid context resource (optional) created with stream_context_create.
* @param boolean $use_prefix Controls the use of a prefix (optional).
* @param boolean $relative Determines if the filename given is relative. Relative paths do not have JPATH_ROOT stripped.
*
* @return mixed
*
* @since 11.1
*/
public function upload($src, $dest, $context = null, $use_prefix = true, $relative = false)
{
if (is_uploaded_file($src))
{
// Make sure it's an uploaded file
return $this->copy($src, $dest, $context, $use_prefix, $relative);
}
else
{
$this->setError(JText::_('JLIB_FILESYSTEM_ERROR_STREAMS_NOT_UPLOADED_FILE'));
return false;
}
}
/**
* Writes a chunk of data to a file.
*
* @param string $filename The file name.
* @param string &$buffer The data to write to the file.
*
* @return boolean
*
* @since 11.1
*/
public function writeFile($filename, &$buffer)
{
if ($this->open($filename, 'w'))
{
$result = $this->write($buffer);
$this->chmod();
$this->close();
return $result;
}
return false;
}
/**
* Determine the appropriate 'filename' of a file
*
* @param string $filename Original filename of the file
* @param string $mode Mode string to retrieve the filename
* @param boolean $use_prefix Controls the use of a prefix
* @param boolean $relative Determines if the filename given is relative. Relative paths do not have JPATH_ROOT stripped.
*
* @return string
*
* @since 11.1
*/
public function _getFilename($filename, $mode, $use_prefix, $relative)
{
if ($use_prefix)
{
// Get rid of binary or t, should be at the end of the string
$tmode = trim($mode, 'btf123456789');
// Check if it's a write mode then add the appropriate prefix
// Get rid of JPATH_ROOT (legacy compat) along the way
if (in_array($tmode, JFilesystemHelper::getWriteModes()))
{
if (!$relative && $this->writeprefix)
{
$filename = str_replace(JPATH_ROOT, '', $filename);
}
$filename = $this->writeprefix . $filename;
}
else
{
if (!$relative && $this->readprefix)
{
$filename = str_replace(JPATH_ROOT, '', $filename);
}
$filename = $this->readprefix . $filename;
}
}
return $filename;
}
/**
* Return the internal file handle
*
* @return File handler
*
* @since 11.1
*/
public function getFileHandle()
{
return $this->_fh;
}
}
PK 3?\V streams/index.htmlnu W+A
PK 3?\) streams/.htaccessnu W+A
Order allow,deny
Deny from all
PK 3?\c streams/string.phpnu W+A _currentstring = &JStringController::getRef(str_replace('string://', '', $path));
if ($this->_currentstring)
{
$this->_len = strlen($this->_currentstring);
$this->_pos = 0;
$this->_stat = $this->url_stat($path, 0);
return true;
}
else
{
return false;
}
}
/**
* Method to retrieve information from a file resource
*
* @return array
*
* @see http://www.php.net/manual/en/streamwrapper.stream-stat.php
* @since 11.1
*/
public function stream_stat()
{
return $this->_stat;
}
/**
* Method to retrieve information about a file.
*
* @param string $path File path or URL to stat
* @param integer $flags Additional flags set by the streams API
*
* @return array
*
* @see http://php.net/manual/en/streamwrapper.url-stat.php
* @since 11.1
*/
public function url_stat($path, $flags = 0)
{
$now = time();
$string = &JStringController::getRef(str_replace('string://', '', $path));
$stat = array(
'dev' => 0,
'ino' => 0,
'mode' => 0,
'nlink' => 1,
'uid' => 0,
'gid' => 0,
'rdev' => 0,
'size' => strlen($string),
'atime' => $now,
'mtime' => $now,
'ctime' => $now,
'blksize' => '512',
'blocks' => ceil(strlen($string) / 512));
return $stat;
}
/**
* Method to read a given number of bytes starting at the current position
* and moving to the end of the string defined by the current position plus the
* given number.
*
* @param integer $count Bytes of data from the current position should be returned.
*
* @return void
*
* @since 11.1
*
* @see http://www.php.net/manual/en/streamwrapper.stream-read.php
*/
public function stream_read($count)
{
$result = substr($this->_currentstring, $this->_pos, $count);
$this->_pos += $count;
return $result;
}
/**
* Stream write, always returning false.
*
* @param string $data The data to write.
*
* @return boolean
*
* @since 11.1
* @note Updating the string is not supported.
*/
public function stream_write($data)
{
// We don't support updating the string.
return false;
}
/**
* Method to get the current position
*
* @return integer The position
*
* @since 11.1
*/
public function stream_tell()
{
return $this->_pos;
}
/**
* End of field check
*
* @return boolean True if at end of field.
*
* @since 11.1
*/
public function stream_eof()
{
if ($this->_pos > $this->_len)
{
return true;
}
return false;
}
/**
* Stream offset
*
* @param integer $offset The starting offset.
* @param integer $whence SEEK_SET, SEEK_CUR, SEEK_END
*
* @return boolean True on success.
*
* @since 11.1
*/
public function stream_seek($offset, $whence)
{
// $whence: SEEK_SET, SEEK_CUR, SEEK_END
if ($offset > $this->_len)
{
// We can't seek beyond our len.
return false;
}
switch ($whence)
{
case SEEK_SET:
$this->_pos = $offset;
break;
case SEEK_CUR:
if (($this->_pos + $offset) < $this->_len)
{
$this->_pos += $offset;
}
else
{
return false;
}
break;
case SEEK_END:
$this->_pos = $this->_len - $offset;
break;
}
return true;
}
/**
* Stream flush, always returns true.
*
* @return boolean
*
* @since 11.1
* @note Data storage is not supported
*/
public function stream_flush()
{
// We don't store data.
return true;
}
}
stream_wrapper_register('string', 'JStreamString') or die(JText::_('JLIB_FILESYSTEM_STREAM_FAILED'));
PK 3?\Wsxo archive.phpnu W+A extract($archivename, $extractdir);
}
break;
case 'tar':
$adapter = JArchive::getAdapter('tar');
if ($adapter)
{
$result = $adapter->extract($archivename, $extractdir);
}
break;
case 'tgz':
// This format is a tarball gzip'd
$untar = true;
case 'gz':
case 'gzip':
// This may just be an individual file (e.g. sql script)
$adapter = JArchive::getAdapter('gzip');
if ($adapter)
{
$config = JFactory::getConfig();
$tmpfname = $config->get('tmp_path') . '/' . uniqid('gzip');
$gzresult = $adapter->extract($archivename, $tmpfname);
if ($gzresult instanceof Exception)
{
@unlink($tmpfname);
return false;
}
if ($untar)
{
// Try to untar the file
$tadapter = JArchive::getAdapter('tar');
if ($tadapter)
{
$result = $tadapter->extract($tmpfname, $extractdir);
}
}
else
{
$path = JPath::clean($extractdir);
JFolder::create($path);
$result = JFile::copy($tmpfname, $path . '/' . JFile::stripExt(JFile::getName(strtolower($archivename))), null, 1);
}
@unlink($tmpfname);
}
break;
case 'tbz2':
// This format is a tarball bzip2'd
$untar = true;
case 'bz2':
case 'bzip2':
// This may just be an individual file (e.g. sql script)
$adapter = JArchive::getAdapter('bzip2');
if ($adapter)
{
$config = JFactory::getConfig();
$tmpfname = $config->get('tmp_path') . '/' . uniqid('bzip2');
$bzresult = $adapter->extract($archivename, $tmpfname);
if ($bzresult instanceof Exception)
{
@unlink($tmpfname);
return false;
}
if ($untar)
{
// Try to untar the file
$tadapter = JArchive::getAdapter('tar');
if ($tadapter)
{
$result = $tadapter->extract($tmpfname, $extractdir);
}
}
else
{
$path = JPath::clean($extractdir);
JFolder::create($path);
$result = JFile::copy($tmpfname, $path . '/' . JFile::stripExt(JFile::getName(strtolower($archivename))), null, 1);
}
@unlink($tmpfname);
}
break;
default:
JError::raiseWarning(10, JText::_('JLIB_FILESYSTEM_UNKNOWNARCHIVETYPE'));
return false;
break;
}
if (!$result || $result instanceof Exception)
{
return false;
}
return true;
}
/**
* Get a file compression adapter.
*
* @param string $type The type of adapter (bzip2|gzip|tar|zip).
*
* @return object JObject
*
* @since 11.1
*/
public static function getAdapter($type)
{
static $adapters;
if (!isset($adapters))
{
$adapters = array();
}
if (!isset($adapters[$type]))
{
// Try to load the adapter object
$class = 'JArchive' . ucfirst($type);
if (!class_exists($class))
{
$path = dirname(__FILE__) . '/archive/' . strtolower($type) . '.php';
if (file_exists($path))
{
require_once $path;
}
else
{
JError::raiseError(500, JText::_('JLIB_FILESYSTEM_UNABLE_TO_LOAD_ARCHIVE'));
}
}
$adapters[$type] = new $class;
}
return $adapters[$type];
}
}
PK 3?\) support/.htaccessnu W+A
Order allow,deny
Deny from all
PK 3?\? support/stringcontroller.phpnu W+A
PK 3?\.&YC YC archive/zip.phpnu W+A
* http://www.zend.com/codex.php?id=535&single=1
*
* Deins125
* http://www.zend.com/codex.php?id=470&single=1
*
* The ZIP compression date code is partially based on code from
* Peter Listiak
*
* This class is inspired from and draws heavily in code and concept from the Compress package of
* The Horde Project
*
* @contributor Chuck Hagenbuch
* @contributor Michael Slusarz
* @contributor Michael Cochrane
*
* @package Joomla.Platform
* @subpackage FileSystem
* @since 11.1
*/
class JArchiveZip extends JObject
{
/**
* ZIP compression methods.
*
* @var array
* @since 11.1
*/
private $_methods = array(0x0 => 'None', 0x1 => 'Shrunk', 0x2 => 'Super Fast', 0x3 => 'Fast', 0x4 => 'Normal', 0x5 => 'Maximum', 0x6 => 'Imploded',
0x8 => 'Deflated');
/**
* Beginning of central directory record.
*
* @var string
* @since 11.1
*/
private $_ctrlDirHeader = "\x50\x4b\x01\x02";
/**
* End of central directory record.
*
* @var string
* @since 11.1
*/
private $_ctrlDirEnd = "\x50\x4b\x05\x06\x00\x00\x00\x00";
/**
* Beginning of file contents.
*
* @var string
* @since 11.1
*/
private $_fileHeader = "\x50\x4b\x03\x04";
/**
* ZIP file data buffer
*
* @var string
* @since 11.1
*/
private $_data = null;
/**
* ZIP file metadata array
*
* @var array
* @since 11.1
*/
private $_metadata = null;
/**
* Create a ZIP compressed file from an array of file data.
*
* @param string $archive Path to save archive.
* @param array $files Array of files to add to archive.
* @param array $options Compression options (unused).
*
* @return boolean True if successful.
*
* @since 11.1
*
* @todo Finish Implementation
*/
public function create($archive, $files, $options = array())
{
// Initialise variables.
$contents = array();
$ctrldir = array();
foreach ($files as $file)
{
$this->_addToZIPFile($file, $contents, $ctrldir);
}
return $this->_createZIPFile($contents, $ctrldir, $archive);
}
/**
* Extract a ZIP compressed file to a given path
*
* @param string $archive Path to ZIP archive to extract
* @param string $destination Path to extract archive into
* @param array $options Extraction options [unused]
*
* @return boolean True if successful
*
* @since 11.1
*/
public function extract($archive, $destination, $options = array())
{
if (!is_file($archive))
{
$this->set('error.message', 'Archive does not exist');
return false;
}
if ($this->hasNativeSupport())
{
return ($this->_extractNative($archive, $destination, $options)) ? true : JError::raiseWarning(100, $this->get('error.message'));
}
else
{
return ($this->_extract($archive, $destination, $options)) ? true : JError::raiseWarning(100, $this->get('error.message'));
}
}
/**
* Tests whether this adapter can unpack files on this computer.
*
* @return boolean True if supported
*
* @since 11.3
*/
public static function isSupported()
{
return (self::hasNativeSupport() || extension_loaded('zlib'));
}
/**
* Method to determine if the server has native zip support for faster handling
*
* @return boolean True if php has native ZIP support
*
* @since 11.1
*/
public static function hasNativeSupport()
{
return (function_exists('zip_open') && function_exists('zip_read'));
}
/**
* Checks to see if the data is a valid ZIP file.
*
* @param string &$data ZIP archive data buffer.
*
* @return boolean True if valid, false if invalid.
*
* @since 11.1
*/
public function checkZipData(&$data)
{
if (strpos($data, $this->_fileHeader) === false)
{
return false;
}
else
{
return true;
}
}
/**
* Extract a ZIP compressed file to a given path using a php based algorithm that only requires zlib support
*
* @param string $archive Path to ZIP archive to extract.
* @param string $destination Path to extract archive into.
* @param array $options Extraction options [unused].
*
* @return boolean True if successful
*
* @since 11.1
*/
private function _extract($archive, $destination, $options)
{
// Initialise variables.
$this->_data = null;
$this->_metadata = null;
if (!extension_loaded('zlib'))
{
$this->set('error.message', JText::_('JLIB_FILESYSTEM_ZIP_NOT_SUPPORTED'));
return false;
}
if (!$this->_data = JFile::read($archive))
{
$this->set('error.message', JText::_('JLIB_FILESYSTEM_ZIP_UNABLE_TO_READ'));
return false;
}
if (!$this->_readZipInfo($this->_data))
{
$this->set('error.message', JText::_('JLIB_FILESYSTEM_ZIP_INFO_FAILED'));
return false;
}
for ($i = 0, $n = count($this->_metadata); $i < $n; $i++)
{
$lastPathCharacter = substr($this->_metadata[$i]['name'], -1, 1);
if ($lastPathCharacter !== '/' && $lastPathCharacter !== '\\')
{
$buffer = $this->_getFileData($i);
$path = JPath::clean($destination . '/' . $this->_metadata[$i]['name']);
// Make sure the destination folder exists
if (!JFolder::create(dirname($path)))
{
$this->set('error.message', JText::_('JLIB_FILESYSTEM_ZIP_UNABLE_TO_CREATE_DESTINATION'));
return false;
}
if (JFile::write($path, $buffer) === false)
{
$this->set('error.message', JText::_('JLIB_FILESYSTEM_ZIP_UNABLE_TO_WRITE_ENTRY'));
return false;
}
}
}
return true;
}
/**
* Extract a ZIP compressed file to a given path using native php api calls for speed
*
* @param string $archive Path to ZIP archive to extract
* @param string $destination Path to extract archive into
* @param array $options Extraction options [unused]
*
* @return boolean True if successful
*
* @since 11.1
*/
private function _extractNative($archive, $destination, $options)
{
$zip = zip_open($archive);
if (is_resource($zip))
{
// Make sure the destination folder exists
if (!JFolder::create($destination))
{
$this->set('error.message', 'Unable to create destination');
return false;
}
// Read files in the archive
while ($file = @zip_read($zip))
{
if (zip_entry_open($zip, $file, "r"))
{
if (substr(zip_entry_name($file), strlen(zip_entry_name($file)) - 1) != "/")
{
$buffer = zip_entry_read($file, zip_entry_filesize($file));
if (JFile::write($destination . '/' . zip_entry_name($file), $buffer) === false)
{
$this->set('error.message', 'Unable to write entry');
return false;
}
zip_entry_close($file);
}
}
else
{
$this->set('error.message', JText::_('JLIB_FILESYSTEM_ZIP_UNABLE_TO_READ_ENTRY'));
return false;
}
}
@zip_close($zip);
}
else
{
$this->set('error.message', JText::_('JLIB_FILESYSTEM_ZIP_UNABLE_TO_OPEN_ARCHIVE'));
return false;
}
return true;
}
/**
* Get the list of files/data from a ZIP archive buffer.
*
*
* KEY: Position in zipfile
* VALUES: 'attr' -- File attributes
* 'crc' -- CRC checksum
* 'csize' -- Compressed file size
* 'date' -- File modification time
* 'name' -- Filename
* 'method'-- Compression method
* 'size' -- Original file size
* 'type' -- File type
*
*
* @param string &$data The ZIP archive buffer.
*
* @return boolean True on success.
*
* @since 11.1
*/
private function _readZipInfo(&$data)
{
// Initialise variables.
$entries = array();
// Find the last central directory header entry
$fhLast = strpos($data, $this->_ctrlDirEnd);
do
{
$last = $fhLast;
}
while (($fhLast = strpos($data, $this->_ctrlDirEnd, $fhLast + 1)) !== false);
// Find the central directory offset
$offset = 0;
if ($last)
{
$endOfCentralDirectory = unpack(
'vNumberOfDisk/vNoOfDiskWithStartOfCentralDirectory/vNoOfCentralDirectoryEntriesOnDisk/' .
'vTotalCentralDirectoryEntries/VSizeOfCentralDirectory/VCentralDirectoryOffset/vCommentLength',
substr($data, $last + 4)
);
$offset = $endOfCentralDirectory['CentralDirectoryOffset'];
}
// Get details from central directory structure.
$fhStart = strpos($data, $this->_ctrlDirHeader, $offset);
$dataLength = strlen($data);
do
{
if ($dataLength < $fhStart + 31)
{
$this->set('error.message', JText::_('JLIB_FILESYSTEM_ZIP_INVALID_ZIP_DATA'));
return false;
}
$info = unpack('vMethod/VTime/VCRC32/VCompressed/VUncompressed/vLength', substr($data, $fhStart + 10, 20));
$name = substr($data, $fhStart + 46, $info['Length']);
$entries[$name] = array(
'attr' => null,
'crc' => sprintf("%08s", dechex($info['CRC32'])),
'csize' => $info['Compressed'],
'date' => null,
'_dataStart' => null,
'name' => $name,
'method' => $this->_methods[$info['Method']],
'_method' => $info['Method'],
'size' => $info['Uncompressed'],
'type' => null
);
$entries[$name]['date'] = mktime(
(($info['Time'] >> 11) & 0x1f),
(($info['Time'] >> 5) & 0x3f),
(($info['Time'] << 1) & 0x3e),
(($info['Time'] >> 21) & 0x07),
(($info['Time'] >> 16) & 0x1f),
((($info['Time'] >> 25) & 0x7f) + 1980)
);
if ($dataLength < $fhStart + 43)
{
$this->set('error.message', 'Invalid ZIP data');
return false;
}
$info = unpack('vInternal/VExternal/VOffset', substr($data, $fhStart + 36, 10));
$entries[$name]['type'] = ($info['Internal'] & 0x01) ? 'text' : 'binary';
$entries[$name]['attr'] = (($info['External'] & 0x10) ? 'D' : '-') . (($info['External'] & 0x20) ? 'A' : '-')
. (($info['External'] & 0x03) ? 'S' : '-') . (($info['External'] & 0x02) ? 'H' : '-') . (($info['External'] & 0x01) ? 'R' : '-');
$entries[$name]['offset'] = $info['Offset'];
// Get details from local file header since we have the offset
$lfhStart = strpos($data, $this->_fileHeader, $entries[$name]['offset']);
if ($dataLength < $lfhStart + 34)
{
$this->set('error.message', 'Invalid ZIP data');
return false;
}
$info = unpack('vMethod/VTime/VCRC32/VCompressed/VUncompressed/vLength/vExtraLength', substr($data, $lfhStart + 8, 25));
$name = substr($data, $lfhStart + 30, $info['Length']);
$entries[$name]['_dataStart'] = $lfhStart + 30 + $info['Length'] + $info['ExtraLength'];
// Bump the max execution time because not using the built in php zip libs makes this process slow.
@set_time_limit(ini_get('max_execution_time'));
}
while ((($fhStart = strpos($data, $this->_ctrlDirHeader, $fhStart + 46)) !== false));
$this->_metadata = array_values($entries);
return true;
}
/**
* Returns the file data for a file by offsest in the ZIP archive
*
* @param integer $key The position of the file in the archive.
*
* @return string Uncompressed file data buffer.
*
* @since 11.1
*/
private function _getFileData($key)
{
if ($this->_metadata[$key]['_method'] == 0x8)
{
return gzinflate(substr($this->_data, $this->_metadata[$key]['_dataStart'], $this->_metadata[$key]['csize']));
}
elseif ($this->_metadata[$key]['_method'] == 0x0)
{
/* Files that aren't compressed. */
return substr($this->_data, $this->_metadata[$key]['_dataStart'], $this->_metadata[$key]['csize']);
}
elseif ($this->_metadata[$key]['_method'] == 0x12)
{
// Is bz2 extension loaded? If not try to load it
if (!extension_loaded('bz2'))
{
if (JPATH_ISWIN)
{
@dl('php_bz2.dll');
}
else
{
@dl('bz2.so');
}
}
// If bz2 extension is successfully loaded use it
if (extension_loaded('bz2'))
{
return bzdecompress(substr($this->_data, $this->_metadata[$key]['_dataStart'], $this->_metadata[$key]['csize']));
}
}
return '';
}
/**
* Converts a UNIX timestamp to a 4-byte DOS date and time format
* (date in high 2-bytes, time in low 2-bytes allowing magnitude
* comparison).
*
* @param integer $unixtime The current UNIX timestamp.
*
* @return integer The current date in a 4-byte DOS format.
*
* @since 11.1
*/
private function _unix2DOSTime($unixtime = null)
{
$timearray = (is_null($unixtime)) ? getdate() : getdate($unixtime);
if ($timearray['year'] < 1980)
{
$timearray['year'] = 1980;
$timearray['mon'] = 1;
$timearray['mday'] = 1;
$timearray['hours'] = 0;
$timearray['minutes'] = 0;
$timearray['seconds'] = 0;
}
return (($timearray['year'] - 1980) << 25) | ($timearray['mon'] << 21) | ($timearray['mday'] << 16) | ($timearray['hours'] << 11) |
($timearray['minutes'] << 5) | ($timearray['seconds'] >> 1);
}
/**
* Adds a "file" to the ZIP archive.
*
* @param array &$file File data array to add
* @param array &$contents An array of existing zipped files.
* @param array &$ctrldir An array of central directory information.
*
* @return void
*
* @since 11.1
*
* @todo Review and finish implementation
*/
private function _addToZIPFile(&$file, &$contents, &$ctrldir)
{
$data = &$file['data'];
$name = str_replace('\\', '/', $file['name']);
/* See if time/date information has been provided. */
$ftime = null;
if (isset($file['time']))
{
$ftime = $file['time'];
}
// Get the hex time.
$dtime = dechex($this->_unix2DosTime($ftime));
$hexdtime = chr(hexdec($dtime[6] . $dtime[7])) . chr(hexdec($dtime[4] . $dtime[5])) . chr(hexdec($dtime[2] . $dtime[3]))
. chr(hexdec($dtime[0] . $dtime[1]));
/* Begin creating the ZIP data. */
$fr = $this->_fileHeader;
/* Version needed to extract. */
$fr .= "\x14\x00";
/* General purpose bit flag. */
$fr .= "\x00\x00";
/* Compression method. */
$fr .= "\x08\x00";
/* Last modification time/date. */
$fr .= $hexdtime;
/* "Local file header" segment. */
$unc_len = strlen($data);
$crc = crc32($data);
$zdata = gzcompress($data);
$zdata = substr(substr($zdata, 0, strlen($zdata) - 4), 2);
$c_len = strlen($zdata);
/* CRC 32 information. */
$fr .= pack('V', $crc);
/* Compressed filesize. */
$fr .= pack('V', $c_len);
/* Uncompressed filesize. */
$fr .= pack('V', $unc_len);
/* Length of filename. */
$fr .= pack('v', strlen($name));
/* Extra field length. */
$fr .= pack('v', 0);
/* File name. */
$fr .= $name;
/* "File data" segment. */
$fr .= $zdata;
/* Add this entry to array. */
$old_offset = strlen(implode('', $contents));
$contents[] = &$fr;
/* Add to central directory record. */
$cdrec = $this->_ctrlDirHeader;
/* Version made by. */
$cdrec .= "\x00\x00";
/* Version needed to extract */
$cdrec .= "\x14\x00";
/* General purpose bit flag */
$cdrec .= "\x00\x00";
/* Compression method */
$cdrec .= "\x08\x00";
/* Last mod time/date. */
$cdrec .= $hexdtime;
/* CRC 32 information. */
$cdrec .= pack('V', $crc);
/* Compressed filesize. */
$cdrec .= pack('V', $c_len);
/* Uncompressed filesize. */
$cdrec .= pack('V', $unc_len);
/* Length of filename. */
$cdrec .= pack('v', strlen($name));
/* Extra field length. */
$cdrec .= pack('v', 0);
/* File comment length. */
$cdrec .= pack('v', 0);
/* Disk number start. */
$cdrec .= pack('v', 0);
/* Internal file attributes. */
$cdrec .= pack('v', 0);
/* External file attributes -'archive' bit set. */
$cdrec .= pack('V', 32);
/* Relative offset of local header. */
$cdrec .= pack('V', $old_offset);
/* File name. */
$cdrec .= $name;
/* Optional extra field, file comment goes here. */
/* Save to central directory array. */
$ctrldir[] = &$cdrec;
}
/**
* Creates the ZIP file.
*
* Official ZIP file format: http://www.pkware.com/appnote.txt
*
* @param array &$contents An array of existing zipped files.
* @param array &$ctrlDir An array of central directory information.
* @param string $path The path to store the archive.
*
* @return boolean True if successful
*
* @since 11.1
*
* @todo Review and finish implementation
*/
private function _createZIPFile(&$contents, &$ctrlDir, $path)
{
$data = implode('', $contents);
$dir = implode('', $ctrlDir);
$buffer = $data . $dir . $this->_ctrlDirEnd . /* Total # of entries "on this disk". */
pack('v', count($ctrlDir)) . /* Total # of entries overall. */
pack('v', count($ctrlDir)) . /* Size of central directory. */
pack('V', strlen($dir)) . /* Offset to start of central dir. */
pack('V', strlen($data)) . /* ZIP file comment length. */
"\x00\x00";
if (JFile::write($path, $buffer) === false)
{
return false;
}
else
{
return true;
}
}
}
PK 3?\V archive/index.htmlnu W+A
PK 3?\/xTf archive/gzip.phpnu W+A
*
* @contributor Michael Slusarz
* @contributor Michael Cochrane
*
* @package Joomla.Platform
* @subpackage FileSystem
* @since 11.1
*/
class JArchiveGzip extends JObject
{
/**
* Gzip file flags.
*
* @var array
* @since 11.1
*/
private $_flags = array('FTEXT' => 0x01, 'FHCRC' => 0x02, 'FEXTRA' => 0x04, 'FNAME' => 0x08, 'FCOMMENT' => 0x10);
/**
* Gzip file data buffer
*
* @var string
* @since 11.1
*/
private $_data = null;
/**
* Extract a Gzip compressed file to a given path
*
* @param string $archive Path to ZIP archive to extract
* @param string $destination Path to extract archive to
* @param array $options Extraction options [unused]
*
* @return boolean True if successful
*
* @since 11.1
*/
public function extract($archive, $destination, $options = array ())
{
// Initialise variables.
$this->_data = null;
if (!extension_loaded('zlib'))
{
$this->set('error.message', JText::_('JLIB_FILESYSTEM_GZIP_NOT_SUPPORTED'));
return JError::raiseWarning(100, $this->get('error.message'));
}
if (!isset($options['use_streams']) || $options['use_streams'] == false)
{
if (!$this->_data = JFile::read($archive))
{
$this->set('error.message', 'Unable to read archive');
return JError::raiseWarning(100, $this->get('error.message'));
}
$position = $this->_getFilePosition();
$buffer = gzinflate(substr($this->_data, $position, strlen($this->_data) - $position));
if (empty($buffer))
{
$this->set('error.message', 'Unable to decompress data');
return JError::raiseWarning(100, $this->get('error.message'));
}
if (JFile::write($destination, $buffer) === false)
{
$this->set('error.message', 'Unable to write archive');
return JError::raiseWarning(100, $this->get('error.message'));
}
}
else
{
// New style! streams!
$input = JFactory::getStream();
$input->set('processingmethod', 'gz'); // use gz
if (!$input->open($archive))
{
$this->set('error.message', JText::_('JLIB_FILESYSTEM_GZIP_UNABLE_TO_READ'));
return JError::raiseWarning(100, $this->get('error.message'));
}
$output = JFactory::getStream();
if (!$output->open($destination, 'w'))
{
$this->set('error.message', JText::_('JLIB_FILESYSTEM_GZIP_UNABLE_TO_WRITE'));
$input->close(); // close the previous file
return JError::raiseWarning(100, $this->get('error.message'));
}
do
{
$this->_data = $input->read($input->get('chunksize', 8196));
if ($this->_data)
{
if (!$output->write($this->_data))
{
$this->set('error.message', JText::_('JLIB_FILESYSTEM_GZIP_UNABLE_TO_WRITE_FILE'));
return JError::raiseWarning(100, $this->get('error.message'));
}
}
}
while ($this->_data);
$output->close();
$input->close();
}
return true;
}
/**
* Tests whether this adapter can unpack files on this computer.
*
* @return boolean True if supported
*
* @since 11.3
*/
public static function isSupported()
{
return extension_loaded('zlib');
}
/**
* Get file data offset for archive
*
* @return integer Data position marker for archive
*
* @since 11.1
*/
public function _getFilePosition()
{
// gzipped file... unpack it first
$position = 0;
$info = @ unpack('CCM/CFLG/VTime/CXFL/COS', substr($this->_data, $position + 2));
if (!$info)
{
$this->set('error.message', JText::_('JLIB_FILESYSTEM_GZIP_UNABLE_TO_DECOMPRESS'));
return false;
}
$position += 10;
if ($info['FLG'] & $this->_flags['FEXTRA'])
{
$XLEN = unpack('vLength', substr($this->_data, $position + 0, 2));
$XLEN = $XLEN['Length'];
$position += $XLEN + 2;
}
if ($info['FLG'] & $this->_flags['FNAME'])
{
$filenamePos = strpos($this->_data, "\x0", $position);
$position = $filenamePos + 1;
}
if ($info['FLG'] & $this->_flags['FCOMMENT'])
{
$commentPos = strpos($this->_data, "\x0", $position);
$position = $commentPos + 1;
}
if ($info['FLG'] & $this->_flags['FHCRC'])
{
$hcrc = unpack('vCRC', substr($this->_data, $position + 0, 2));
$hcrc = $hcrc['CRC'];
$position += 2;
}
return $position;
}
}
PK 3?\ archive/bzip2.phpnu W+A _data = null;
if (!extension_loaded('bz2'))
{
$this->set('error.message', JText::_('JLIB_FILESYSTEM_BZIP_NOT_SUPPORTED'));
return JError::raiseWarning(100, $this->get('error.message'));
}
if (!isset($options['use_streams']) || $options['use_streams'] == false)
{
// Old style: read the whole file and then parse it
if (!$this->_data = JFile::read($archive))
{
$this->set('error.message', 'Unable to read archive');
return JError::raiseWarning(100, $this->get('error.message'));
}
$buffer = bzdecompress($this->_data);
unset($this->_data);
if (empty($buffer))
{
$this->set('error.message', 'Unable to decompress data');
return JError::raiseWarning(100, $this->get('error.message'));
}
if (JFile::write($destination, $buffer) === false)
{
$this->set('error.message', 'Unable to write archive');
return JError::raiseWarning(100, $this->get('error.message'));
}
}
else
{
// New style! streams!
$input = JFactory::getStream();
$input->set('processingmethod', 'bz'); // use bzip
if (!$input->open($archive))
{
$this->set('error.message', JText::_('JLIB_FILESYSTEM_BZIP_UNABLE_TO_READ'));
return JError::raiseWarning(100, $this->get('error.message'));
}
$output = JFactory::getStream();
if (!$output->open($destination, 'w'))
{
$this->set('error.message', JText::_('JLIB_FILESYSTEM_BZIP_UNABLE_TO_WRITE'));
$input->close(); // close the previous file
return JError::raiseWarning(100, $this->get('error.message'));
}
do
{
$this->_data = $input->read($input->get('chunksize', 8196));
if ($this->_data)
{
if (!$output->write($this->_data))
{
$this->set('error.message', JText::_('JLIB_FILESYSTEM_BZIP_UNABLE_TO_WRITE_FILE'));
return JError::raiseWarning(100, $this->get('error.message'));
}
}
}
while ($this->_data);
$output->close();
$input->close();
}
return true;
}
/**
* Tests whether this adapter can unpack files on this computer.
*
* @return boolean True if supported
*
* @since 11.3
*/
public static function isSupported()
{
self::loadExtension();
return extension_loaded('bz2');
}
/**
* Load the bzip2 extension
*
* @return void
*
* @since 11.3
*/
private static function loadExtension()
{
// Is bz2 extension loaded? If not try to load it
if (!extension_loaded('bz2'))
{
if (JPATH_ISWIN)
{
@ dl('php_bz2.dll');
}
else
{
@ dl('bz2.so');
}
}
}
}
PK 3?\) archive/.htaccessnu W+A
Order allow,deny
Deny from all
PK 3?\N archive/tar.phpnu W+A
*
* @contributor Michael Slusarz
* @contributor Michael Cochrane
*
* @package Joomla.Platform
* @subpackage FileSystem
* @since 11.1
*/
class JArchiveTar extends JObject
{
/**
* Tar file types.
*
* @var array
* @since 11.1
*/
private $_types = array(
0x0 => 'Unix file',
0x30 => 'File',
0x31 => 'Link',
0x32 => 'Symbolic link',
0x33 => 'Character special file',
0x34 => 'Block special file',
0x35 => 'Directory',
0x36 => 'FIFO special file',
0x37 => 'Contiguous file');
/**
* Tar file data buffer
*
* @var string
* @since 11.1
*/
private $_data = null;
/**
* Tar file metadata array
*
* @var array
* @since 11.1
*/
private $_metadata = null;
/**
* Extract a ZIP compressed file to a given path
*
* @param string $archive Path to ZIP archive to extract
* @param string $destination Path to extract archive into
* @param array $options Extraction options [unused]
*
* @return boolean True if successful
*
* @since 11.1
*/
public function extract($archive, $destination, $options = array())
{
// Initialise variables.
$this->_data = null;
$this->_metadata = null;
if (!$this->_data = JFile::read($archive))
{
$this->set('error.message', 'Unable to read archive');
return JError::raiseWarning(100, $this->get('error.message'));
}
if (!$this->_getTarInfo($this->_data))
{
return JError::raiseWarning(100, $this->get('error.message'));
}
for ($i = 0, $n = count($this->_metadata); $i < $n; $i++)
{
$type = strtolower($this->_metadata[$i]['type']);
if ($type == 'file' || $type == 'unix file')
{
$buffer = $this->_metadata[$i]['data'];
$path = JPath::clean($destination . '/' . $this->_metadata[$i]['name']);
// Make sure the destination folder exists
if (!JFolder::create(dirname($path)))
{
$this->set('error.message', 'Unable to create destination');
return JError::raiseWarning(100, $this->get('error.message'));
}
if (JFile::write($path, $buffer) === false)
{
$this->set('error.message', 'Unable to write entry');
return JError::raiseWarning(100, $this->get('error.message'));
}
}
}
return true;
}
/**
* Tests whether this adapter can unpack files on this computer.
*
* @return boolean True if supported
*
* @since 11.3
*/
public static function isSupported()
{
return true;
}
/**
* Get the list of files/data from a Tar archive buffer.
*
* @param string &$data The Tar archive buffer.
*
* @return array Archive metadata array
*
* KEY: Position in the array
* VALUES: 'attr' -- File attributes
* 'data' -- Raw file contents
* 'date' -- File modification time
* 'name' -- Filename
* 'size' -- Original file size
* 'type' -- File type
*
*
* @since 11.1
*/
protected function _getTarInfo(& $data)
{
$position = 0;
$return_array = array();
while ($position < strlen($data))
{
$info = @unpack(
"a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/a8checksum/Ctypeflag/a100link/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor",
substr($data, $position)
);
if (!$info)
{
$this->set('error.message', 'Unable to decompress data');
return false;
}
$position += 512;
$contents = substr($data, $position, octdec($info['size']));
$position += ceil(octdec($info['size']) / 512) * 512;
if ($info['filename'])
{
$file = array(
'attr' => null,
'data' => null,
'date' => octdec($info['mtime']),
'name' => trim($info['filename']),
'size' => octdec($info['size']),
'type' => isset($this->_types[$info['typeflag']]) ? $this->_types[$info['typeflag']] : null);
if (($info['typeflag'] == 0) || ($info['typeflag'] == 0x30) || ($info['typeflag'] == 0x35))
{
/* File or folder. */
$file['data'] = $contents;
$mode = hexdec(substr($info['mode'], 4, 3));
$file['attr'] = (($info['typeflag'] == 0x35) ? 'd' : '-') . (($mode & 0x400) ? 'r' : '-') . (($mode & 0x200) ? 'w' : '-') .
(($mode & 0x100) ? 'x' : '-') . (($mode & 0x040) ? 'r' : '-') . (($mode & 0x020) ? 'w' : '-') . (($mode & 0x010) ? 'x' : '-') .
(($mode & 0x004) ? 'r' : '-') . (($mode & 0x002) ? 'w' : '-') . (($mode & 0x001) ? 'x' : '-');
}
else
{
/* Some other type. */
}
$return_array[] = $file;
}
}
$this->_metadata = $return_array;
return true;
}
}
PK 3?\S)I I
folder.phpnu W+A PK 3?\'&1 1 LI file.phpnu W+A PK 3?\V
;{ index.htmlnu W+A PK 3?\W( { path.phpnu W+A PK 3?\
O helper.phpnu W+A PK 3?\) .htaccessnu W+A PK 3?\~ ~
F stream.phpnu W+A PK 3?\V F, streams/index.htmlnu W+A PK 3?\) , streams/.htaccessnu W+A PK 3?\c g- streams/string.phpnu W+A PK 3?\Wsxo B archive.phpnu W+A PK 3?\) S support/.htaccessnu W+A PK 3?\? T support/stringcontroller.phpnu W+A PK 3?\V Y support/index.htmlnu W+A PK 3?\.&YC YC Y archive/zip.phpnu W+A PK 3?\V archive/index.htmlnu W+A PK 3?\/xTf archive/gzip.phpnu W+A PK 3?\ ° archive/bzip2.phpnu W+A PK 3?\) archive/.htaccessnu W+A PK 3?\N M archive/tar.phpnu W+A PK " $