[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/vendor/joomla/filesystem/src/ -> File.php (source)

   1  <?php
   2  /**
   3   * Part of the Joomla Framework Filesystem Package
   4   *
   5   * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved.
   6   * @license    GNU General Public License version 2 or later; see LICENSE
   7   */
   8  
   9  namespace Joomla\Filesystem;
  10  
  11  use Joomla\Filesystem\Exception\FilesystemException;
  12  
  13  /**
  14   * A File handling class
  15   *
  16   * @since  1.0
  17   */
  18  class File
  19  {
  20      /**
  21       * Strips the last extension off of a file name
  22       *
  23       * @param   string  $file  The file name
  24       *
  25       * @return  string  The file name without the extension
  26       *
  27       * @since   1.0
  28       */
  29  	public static function stripExt($file)
  30      {
  31          return preg_replace('#\.[^.]*$#', '', $file);
  32      }
  33  
  34      /**
  35       * Makes the file name safe to use
  36       *
  37       * @param   string  $file        The name of the file [not full path]
  38       * @param   array   $stripChars  Array of regex (by default will remove any leading periods)
  39       *
  40       * @return  string  The sanitised string
  41       *
  42       * @since   1.0
  43       */
  44  	public static function makeSafe($file, array $stripChars = ['#^\.#'])
  45      {
  46          $regex = array_merge(['#(\.){2,}#', '#[^A-Za-z0-9\.\_\- ]#'], $stripChars);
  47  
  48          $file = preg_replace($regex, '', $file);
  49  
  50          // Remove any trailing dots, as those aren't ever valid file names.
  51          $file = rtrim($file, '.');
  52  
  53          return $file;
  54      }
  55  
  56      /**
  57       * Copies a file
  58       *
  59       * @param   string   $src         The path to the source file
  60       * @param   string   $dest        The path to the destination file
  61       * @param   string   $path        An optional base path to prefix to the file names
  62       * @param   boolean  $useStreams  True to use streams
  63       *
  64       * @return  boolean  True on success
  65       *
  66       * @since   1.0
  67       * @throws  FilesystemException
  68       * @throws  \UnexpectedValueException
  69       */
  70  	public static function copy($src, $dest, $path = null, $useStreams = false)
  71      {
  72          // Prepend a base path if it exists
  73          if ($path)
  74          {
  75              $src  = Path::clean($path . '/' . $src);
  76              $dest = Path::clean($path . '/' . $dest);
  77          }
  78  
  79          // Check src path
  80          if (!is_readable($src))
  81          {
  82              throw new \UnexpectedValueException(
  83                  sprintf(
  84                      "%s: Cannot find or read file: %s",
  85                      __METHOD__,
  86                      Path::removeRoot($src)
  87                  )
  88              );
  89          }
  90  
  91          if ($useStreams)
  92          {
  93              $stream = Stream::getStream();
  94  
  95              if (!$stream->copy($src, $dest, null, false))
  96              {
  97                  throw new FilesystemException(sprintf('%1$s(%2$s, %3$s): %4$s', __METHOD__, $src, $dest, $stream->getError()));
  98              }
  99  
 100              self::invalidateFileCache($dest);
 101  
 102              return true;
 103          }
 104  
 105          if (!@ copy($src, $dest))
 106          {
 107              throw new FilesystemException(__METHOD__ . ': Copy failed.');
 108          }
 109  
 110          self::invalidateFileCache($dest);
 111  
 112          return true;
 113      }
 114  
 115      /**
 116       * Delete a file or array of files
 117       *
 118       * @param   mixed  $file  The file name or an array of file names
 119       *
 120       * @return  boolean  True on success
 121       *
 122       * @since   1.0
 123       * @throws  FilesystemException
 124       */
 125  	public static function delete($file)
 126      {
 127          $files = (array) $file;
 128  
 129          foreach ($files as $file)
 130          {
 131              $file     = Path::clean($file);
 132              $filename = basename($file);
 133  
 134              if (!Path::canChmod($file))
 135              {
 136                  throw new FilesystemException(__METHOD__ . ': Failed deleting inaccessible file ' . $filename);
 137              }
 138  
 139              // Try making the file writable first. If it's read-only, it can't be deleted
 140              // on Windows, even if the parent folder is writable
 141              @chmod($file, 0777);
 142  
 143              // In case of restricted permissions we zap it one way or the other
 144              // as long as the owner is either the webserver or the ftp
 145              if (!@ unlink($file))
 146              {
 147                  throw new FilesystemException(__METHOD__ . ': Failed deleting ' . $filename);
 148              }
 149  
 150              self::invalidateFileCache($file);
 151          }
 152  
 153          return true;
 154      }
 155  
 156      /**
 157       * Moves a file
 158       *
 159       * @param   string   $src         The path to the source file
 160       * @param   string   $dest        The path to the destination file
 161       * @param   string   $path        An optional base path to prefix to the file names
 162       * @param   boolean  $useStreams  True to use streams
 163       *
 164       * @return  boolean  True on success
 165       *
 166       * @since   1.0
 167       * @throws  FilesystemException
 168       */
 169  	public static function move($src, $dest, $path = '', $useStreams = false)
 170      {
 171          if ($path)
 172          {
 173              $src  = Path::clean($path . '/' . $src);
 174              $dest = Path::clean($path . '/' . $dest);
 175          }
 176  
 177          // Check src path
 178          if (!is_readable($src))
 179          {
 180              return 'Cannot find source file.';
 181          }
 182  
 183          if ($useStreams)
 184          {
 185              $stream = Stream::getStream();
 186  
 187              if (!$stream->move($src, $dest, null, false))
 188              {
 189                  throw new FilesystemException(__METHOD__ . ': ' . $stream->getError());
 190              }
 191  
 192              self::invalidateFileCache($dest);
 193  
 194              return true;
 195          }
 196  
 197          if (!@ rename($src, $dest))
 198          {
 199              throw new FilesystemException(__METHOD__ . ': Rename failed.');
 200          }
 201  
 202          self::invalidateFileCache($dest);
 203  
 204          return true;
 205      }
 206  
 207      /**
 208       * Write contents to a file
 209       *
 210       * @param   string   $file          The full file path
 211       * @param   string   $buffer        The buffer to write
 212       * @param   boolean  $useStreams    Use streams
 213       * @param   boolean  $appendToFile  Append to the file and not overwrite it.
 214       *
 215       * @return  boolean  True on success
 216       *
 217       * @since   1.0
 218       */
 219  	public static function write($file, &$buffer, $useStreams = false, $appendToFile = false)
 220      {
 221          @set_time_limit(ini_get('max_execution_time'));
 222  
 223          // If the destination directory doesn't exist we need to create it
 224          if (!file_exists(\dirname($file)))
 225          {
 226              Folder::create(\dirname($file));
 227          }
 228  
 229          if ($useStreams)
 230          {
 231              $stream = Stream::getStream();
 232  
 233              // Beef up the chunk size to a meg
 234              $stream->set('chunksize', (1024 * 1024));
 235              $stream->writeFile($file, $buffer, $appendToFile);
 236  
 237              self::invalidateFileCache($file);
 238  
 239              return true;
 240          }
 241  
 242          $file = Path::clean($file);
 243  
 244          // Set the required flag to only append to the file and not overwrite it
 245          if ($appendToFile === true)
 246          {
 247              $res = \is_int(file_put_contents($file, $buffer, \FILE_APPEND));
 248          }
 249          else
 250          {
 251              $res = \is_int(file_put_contents($file, $buffer));
 252          }
 253  
 254          self::invalidateFileCache($file);
 255  
 256          return $res;
 257      }
 258  
 259      /**
 260       * Moves an uploaded file to a destination folder
 261       *
 262       * @param   string   $src         The name of the php (temporary) uploaded file
 263       * @param   string   $dest        The path (including filename) to move the uploaded file to
 264       * @param   boolean  $useStreams  True to use streams
 265       *
 266       * @return  boolean  True on success
 267       *
 268       * @since   1.0
 269       * @throws  FilesystemException
 270       */
 271  	public static function upload($src, $dest, $useStreams = false)
 272      {
 273          // Ensure that the path is valid and clean
 274          $dest = Path::clean($dest);
 275  
 276          // Create the destination directory if it does not exist
 277          $baseDir = \dirname($dest);
 278  
 279          if (!is_dir($baseDir))
 280          {
 281              Folder::create($baseDir);
 282          }
 283  
 284          if ($useStreams)
 285          {
 286              $stream = Stream::getStream();
 287  
 288              if (!$stream->upload($src, $dest, null, false))
 289              {
 290                  throw new FilesystemException(sprintf('%1$s(%2$s, %3$s): %4$s', __METHOD__, $src, $dest, $stream->getError()));
 291              }
 292  
 293              self::invalidateFileCache($dest);
 294  
 295              return true;
 296          }
 297  
 298          if (is_writable($baseDir) && move_uploaded_file($src, $dest))
 299          {
 300              // Short circuit to prevent file permission errors
 301              if (Path::setPermissions($dest))
 302              {
 303                  self::invalidateFileCache($dest);
 304  
 305                  return true;
 306              }
 307  
 308              throw new FilesystemException(__METHOD__ . ': Failed to change file permissions.');
 309          }
 310  
 311          throw new FilesystemException(__METHOD__ . ': Failed to move file.');
 312      }
 313  
 314      /**
 315       * Invalidate any opcache for a newly written file immediately, if opcache* functions exist and if this was a PHP file.
 316       *
 317       * @param   string  $file  The path to the file just written to, to flush from opcache
 318       *
 319       * @return void
 320       */
 321  	public static function invalidateFileCache($file)
 322      {
 323          if (function_exists('opcache_invalidate'))
 324          {
 325              $info = pathinfo($file);
 326  
 327              if (isset($info['extension']) && $info['extension'] === 'php')
 328              {
 329                  // Force invalidation to be absolutely sure the opcache is cleared for this file.
 330                  opcache_invalidate($file, true);
 331              }
 332          }
 333      }
 334  }


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer