You've already forked joomla_test
							
							
		
			
				
	
	
		
			544 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			544 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| /**
 | |
|  * @package     Joomla.Platform
 | |
|  * @subpackage  FileSystem
 | |
|  *
 | |
|  * @copyright   Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
 | |
|  * @license     GNU General Public License version 2 or later; see LICENSE
 | |
|  */
 | |
| 
 | |
| defined('JPATH_PLATFORM') or die;
 | |
| 
 | |
| jimport('joomla.filesystem.path');
 | |
| 
 | |
| /**
 | |
|  * A File handling class
 | |
|  *
 | |
|  * @package     Joomla.Platform
 | |
|  * @subpackage  FileSystem
 | |
|  * @since       11.1
 | |
|  */
 | |
| class JFile
 | |
| {
 | |
| 	/**
 | |
| 	 * Gets the extension of a file name
 | |
| 	 *
 | |
| 	 * @param   string  $file  The file name
 | |
| 	 *
 | |
| 	 * @return  string  The file extension
 | |
| 	 *
 | |
| 	 * @since   11.1
 | |
| 	 */
 | |
| 	public static function getExt($file)
 | |
| 	{
 | |
| 		$dot = strrpos($file, '.') + 1;
 | |
| 
 | |
| 		return substr($file, $dot);
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Strips the last extension off of a file name
 | |
| 	 *
 | |
| 	 * @param   string  $file  The file name
 | |
| 	 *
 | |
| 	 * @return  string  The file name without the extension
 | |
| 	 *
 | |
| 	 * @since   11.1
 | |
| 	 */
 | |
| 	public static function stripExt($file)
 | |
| 	{
 | |
| 		return preg_replace('#\.[^.]*$#', '', $file);
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Makes file name safe to use
 | |
| 	 *
 | |
| 	 * @param   string  $file  The name of the file [not full path]
 | |
| 	 *
 | |
| 	 * @return  string  The sanitised string
 | |
| 	 *
 | |
| 	 * @since   11.1
 | |
| 	 */
 | |
| 	public static function makeSafe($file)
 | |
| 	{
 | |
| 		// Remove any trailing dots, as those aren't ever valid file names.
 | |
| 		$file = rtrim($file, '.');
 | |
| 
 | |
| 		$regex = array('#(\.){2,}#', '#[^A-Za-z0-9\.\_\- ]#', '#^\.#');
 | |
| 
 | |
| 		return preg_replace($regex, '', $file);
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Copies 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 copy($src, $dest, $path = null, $use_streams = false)
 | |
| 	{
 | |
| 		// Prepend a base path if it exists
 | |
| 		if ($path)
 | |
| 		{
 | |
| 			$src = JPath::clean($path . '/' . $src);
 | |
| 			$dest = JPath::clean($path . '/' . $dest);
 | |
| 		}
 | |
| 
 | |
| 		// Check src path
 | |
| 		if (!is_readable($src))
 | |
| 		{
 | |
| 			JLog::add(JText::sprintf('JLIB_FILESYSTEM_ERROR_JFILE_FIND_COPY', $src), JLog::WARNING, 'jerror');
 | |
| 			return false;
 | |
| 		}
 | |
| 
 | |
| 		if ($use_streams)
 | |
| 		{
 | |
| 			$stream = JFactory::getStream();
 | |
| 
 | |
| 			if (!$stream->copy($src, $dest))
 | |
| 			{
 | |
| 				JLog::add(JText::sprintf('JLIB_FILESYSTEM_ERROR_JFILE_STREAMS', $src, $dest, $stream->getError()), JLog::WARNING, 'jerror');
 | |
| 				return false;
 | |
| 			}
 | |
| 
 | |
| 			return true;
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			$FTPOptions = JClientHelper::getCredentials('ftp');
 | |
| 
 | |
| 			if ($FTPOptions['enabled'] == 1)
 | |
| 			{
 | |
| 				// Connect the FTP client
 | |
| 				$ftp = JClientFtp::getInstance($FTPOptions['host'], $FTPOptions['port'], array(), $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))
 | |
| 				{
 | |
| 					JLog::add(JText::_('JLIB_FILESYSTEM_ERROR_COPY_FAILED'), JLog::WARNING, 'jerror');
 | |
| 					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)
 | |
| 	{
 | |
| 		$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
 | |
| 			$ftp = JClientFtp::getInstance($FTPOptions['host'], $FTPOptions['port'], array(), $FTPOptions['user'], $FTPOptions['pass']);
 | |
| 		}
 | |
| 
 | |
| 		foreach ($files as $file)
 | |
| 		{
 | |
| 			$file = JPath::clean($file);
 | |
| 
 | |
| 			// 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);
 | |
| 				JLog::add(JText::sprintf('JLIB_FILESYSTEM_DELETE_FAILED', $filename), JLog::WARNING, 'jerror');
 | |
| 				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))
 | |
| 			{
 | |
| 				JLog::add(JText::sprintf('JLIB_FILESYSTEM_ERROR_JFILE_MOVE_STREAMS', $stream->getError()), JLog::WARNING, 'jerror');
 | |
| 				return false;
 | |
| 			}
 | |
| 
 | |
| 			return true;
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			$FTPOptions = JClientHelper::getCredentials('ftp');
 | |
| 
 | |
| 			if ($FTPOptions['enabled'] == 1)
 | |
| 			{
 | |
| 				// Connect the FTP client
 | |
| 				$ftp = JClientFtp::getInstance($FTPOptions['host'], $FTPOptions['port'], array(), $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))
 | |
| 				{
 | |
| 					JLog::add(JText::_('JLIB_FILESYSTEM_ERROR_RENAME_FILE'), JLog::WARNING, 'jerror');
 | |
| 					return false;
 | |
| 				}
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				if (!@ rename($src, $dest))
 | |
| 				{
 | |
| 					JLog::add(JText::_('JLIB_FILESYSTEM_ERROR_RENAME_FILE'), JLog::WARNING, 'jerror');
 | |
| 					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
 | |
| 	 * @deprecated  13.3 (Platform) & 4.0 (CMS) - Use the native file_get_contents() instead.
 | |
| 	 */
 | |
| 	public static function read($filename, $incpath = false, $amount = 0, $chunksize = 8192, $offset = 0)
 | |
| 	{
 | |
| 		JLog::add(__METHOD__ . ' is deprecated. Use native file_get_contents() syntax.', JLog::WARNING, 'deprecated');
 | |
| 
 | |
| 		$data = null;
 | |
| 		if ($amount && $chunksize > $amount)
 | |
| 		{
 | |
| 			$chunksize = $amount;
 | |
| 		}
 | |
| 
 | |
| 		if (false === $fh = fopen($filename, 'rb', $incpath))
 | |
| 		{
 | |
| 			JLog::add(JText::sprintf('JLIB_FILESYSTEM_ERROR_READ_UNABLE_TO_OPEN_FILE', $filename), JLog::WARNING, 'jerror');
 | |
| 			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))
 | |
| 			{
 | |
| 				JLog::add(JText::sprintf('JLIB_FILESYSTEM_ERROR_WRITE_STREAMS', $file, $stream->getError()), JLog::WARNING, 'jerror');
 | |
| 				return false;
 | |
| 			}
 | |
| 
 | |
| 			return true;
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			$FTPOptions = JClientHelper::getCredentials('ftp');
 | |
| 
 | |
| 			if ($FTPOptions['enabled'] == 1)
 | |
| 			{
 | |
| 				// Connect the FTP client
 | |
| 				$ftp = JClientFtp::getInstance($FTPOptions['host'], $FTPOptions['port'], array(), $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))
 | |
| 			{
 | |
| 				JLog::add(JText::sprintf('JLIB_FILESYSTEM_ERROR_UPLOAD', $stream->getError()), JLog::WARNING, 'jerror');
 | |
| 				return false;
 | |
| 			}
 | |
| 
 | |
| 			return true;
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			$FTPOptions = JClientHelper::getCredentials('ftp');
 | |
| 			$ret = false;
 | |
| 
 | |
| 			if ($FTPOptions['enabled'] == 1)
 | |
| 			{
 | |
| 				// Connect the FTP client
 | |
| 				$ftp = JClientFtp::getInstance($FTPOptions['host'], $FTPOptions['port'], array(), $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
 | |
| 				{
 | |
| 					JLog::add(JText::_('JLIB_FILESYSTEM_ERROR_WARNFS_ERR02'), JLog::WARNING, 'jerror');
 | |
| 				}
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				if (is_writeable($baseDir) && move_uploaded_file($src, $dest))
 | |
| 				{
 | |
| 					// Short circuit to prevent file permission errors
 | |
| 					if (JPath::setPermissions($dest))
 | |
| 					{
 | |
| 						$ret = true;
 | |
| 					}
 | |
| 					else
 | |
| 					{
 | |
| 						JLog::add(JText::_('JLIB_FILESYSTEM_ERROR_WARNFS_ERR01'), JLog::WARNING, 'jerror');
 | |
| 					}
 | |
| 				}
 | |
| 				else
 | |
| 				{
 | |
| 					JLog::add(JText::_('JLIB_FILESYSTEM_ERROR_WARNFS_ERR02'), JLog::WARNING, 'jerror');
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 			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
 | |
| 	 * @deprecated  13.3 (Platform) & 4.0 (CMS) - Use basename() instead.
 | |
| 	 */
 | |
| 	public static function getName($file)
 | |
| 	{
 | |
| 		JLog::add(__METHOD__ . ' is deprecated. Use native basename() syntax.', JLog::WARNING, 'deprecated');
 | |
| 
 | |
| 		// Convert back slashes to forward slashes
 | |
| 		$file = str_replace('\\', '/', $file);
 | |
| 		$slash = strrpos($file, '/');
 | |
| 		if ($slash !== false)
 | |
| 		{
 | |
| 
 | |
| 			return substr($file, $slash + 1);
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 
 | |
| 			return $file;
 | |
| 		}
 | |
| 	}
 | |
| }
 | 
