[ Index ]

PHP Cross Reference of Joomla 1.5.26 DE

title

Body

[close]

/libraries/joomla/filesystem/ -> folder.php (source)

   1  <?php
   2  /**
   3   * @version        $Id: folder.php 16421 2010-04-24 23:57:12Z dextercowley $
   4   * @package        Joomla.Framework
   5   * @subpackage    FileSystem
   6   * @copyright    Copyright (C) 2005 - 2010 Open Source Matters. All rights reserved.
   7   * @license        GNU/GPL, see LICENSE.php
   8   * Joomla! is free software. This version may have been modified pursuant
   9   * to the GNU General Public License, and as distributed it includes or
  10   * is derivative of works licensed under the GNU General Public License or
  11   * other free or open source software licenses.
  12   * See COPYRIGHT.php for copyright notices and details.
  13   */
  14  
  15  // Check to ensure this file is within the rest of the framework
  16  defined('JPATH_BASE') or die();
  17  
  18  jimport('joomla.filesystem.path');
  19  
  20  /**
  21   * A Folder handling class
  22   *
  23   * @static
  24   * @package     Joomla.Framework
  25   * @subpackage    FileSystem
  26   * @since        1.5
  27   */
  28  class JFolder
  29  {
  30      /**
  31       * Copy a folder.
  32       *
  33       * @param    string    The path to the source folder.
  34       * @param    string    The path to the destination folder.
  35       * @param    string    An optional base path to prefix to the file names.
  36       * @param    boolean    Optionally force folder/file overwrites.
  37       * @return    mixed    JError object on failure or boolean True on success.
  38       * @since    1.5
  39       */
  40  	function copy($src, $dest, $path = '', $force = false)
  41      {
  42          // Initialize variables
  43          jimport('joomla.client.helper');
  44          $ftpOptions = JClientHelper::getCredentials('ftp');
  45  
  46          if ($path) {
  47              $src = JPath::clean($path . DS . $src);
  48              $dest = JPath::clean($path . DS . $dest);
  49          }
  50  
  51          // Eliminate trailing directory separators, if any
  52          $src = rtrim($src, DS);
  53          $dest = rtrim($dest, DS);
  54  
  55          if (!JFolder::exists($src)) {
  56              return JError::raiseError(-1, JText::_('Cannot find source folder'));
  57          }
  58          if (JFolder::exists($dest) && !$force) {
  59              return JError::raiseError(-1, JText::_('Folder already exists'));
  60          }
  61  
  62          // Make sure the destination exists
  63          if (! JFolder::create($dest)) {
  64              return JError::raiseError(-1, JText::_('Unable to create target folder'));
  65          }
  66  
  67          if ($ftpOptions['enabled'] == 1)
  68          {
  69              // Connect the FTP client
  70              jimport('joomla.client.ftp');
  71              $ftp = &JFTP::getInstance(
  72                  $ftpOptions['host'], $ftpOptions['port'], null,
  73                  $ftpOptions['user'], $ftpOptions['pass']
  74              );
  75  
  76              if (!($dh = @opendir($src))) {
  77                  return JError::raiseError(-1, JText::_('Unable to open source folder'));
  78              }
  79              // Walk through the directory copying files and recursing into folders.
  80              while (($file = readdir($dh)) !== false) {
  81                  $sfid = $src . DS . $file;
  82                  $dfid = $dest . DS . $file;
  83                  switch (filetype($sfid)) {
  84                      case 'dir':
  85                          if ($file != '.' && $file != '..') {
  86                              $ret = JFolder::copy($sfid, $dfid, null, $force);
  87                              if ($ret !== true) {
  88                                  return $ret;
  89                              }
  90                          }
  91                          break;
  92  
  93                      case 'file':
  94                          // Translate path for the FTP account
  95                          $dfid = JPath::clean(str_replace(JPATH_ROOT, $ftpOptions['root'], $dfid), '/');
  96                          if (! $ftp->store($sfid, $dfid)) {
  97                              return JError::raiseError(-1, JText::_('Copy failed'));
  98                          }
  99                          break;
 100                  }
 101              }
 102          } else {
 103              if (!($dh = @opendir($src))) {
 104                  return JError::raiseError(-1, JText::_('Unable to open source folder'));
 105              }
 106              // Walk through the directory copying files and recursing into folders.
 107              while (($file = readdir($dh)) !== false) {
 108                  $sfid = $src . DS . $file;
 109                  $dfid = $dest . DS . $file;
 110                  switch (filetype($sfid)) {
 111                      case 'dir':
 112                          if ($file != '.' && $file != '..') {
 113                              $ret = JFolder::copy($sfid, $dfid, null, $force);
 114                              if ($ret !== true) {
 115                                  return $ret;
 116                              }
 117                          }
 118                          break;
 119  
 120                      case 'file':
 121                          if (!@copy($sfid, $dfid)) {
 122                              return JError::raiseError(-1, JText::_('Copy failed'));
 123                          }
 124                          break;
 125                  }
 126              }
 127          }
 128          return true;
 129      }
 130  
 131      /**
 132       * Create a folder -- and all necessary parent folders.
 133       *
 134       * @param string A path to create from the base path.
 135       * @param int Directory permissions to set for folders created.
 136       * @return boolean True if successful.
 137       * @since 1.5
 138       */
 139  	function create($path = '', $mode = 0755)
 140      {
 141          // Initialize variables
 142          jimport('joomla.client.helper');
 143          $ftpOptions = JClientHelper::getCredentials('ftp');
 144          static $nested = 0;
 145  
 146          // Check to make sure the path valid and clean
 147          $path = JPath::clean($path);
 148  
 149          // Check if parent dir exists
 150          $parent = dirname($path);
 151          if (!JFolder::exists($parent)) {
 152              // Prevent infinite loops!
 153              $nested++;
 154              if (($nested > 20) || ($parent == $path)) {
 155                  JError::raiseWarning(
 156                      'SOME_ERROR_CODE',
 157                      'JFolder::create: ' . JText::_('Infinite loop detected')
 158                  );
 159                  $nested--;
 160                  return false;
 161              }
 162  
 163              // Create the parent directory
 164              if (JFolder::create($parent, $mode) !== true) {
 165                  // JFolder::create throws an error
 166                  $nested--;
 167                  return false;
 168              }
 169  
 170              // OK, parent directory has been created
 171              $nested--;
 172          }
 173  
 174          // Check if dir already exists
 175          if (JFolder::exists($path)) {
 176              return true;
 177          }
 178  
 179          // Check for safe mode
 180          if ($ftpOptions['enabled'] == 1) {
 181              // Connect the FTP client
 182              jimport('joomla.client.ftp');
 183              $ftp = &JFTP::getInstance(
 184                  $ftpOptions['host'], $ftpOptions['port'], null,
 185                  $ftpOptions['user'], $ftpOptions['pass']
 186              );
 187  
 188              // Translate path to FTP path
 189              $path = JPath::clean(str_replace(JPATH_ROOT, $ftpOptions['root'], $path), '/');
 190              $ret = $ftp->mkdir($path);
 191              $ftp->chmod($path, $mode);
 192          } else {
 193              // We need to get and explode the open_basedir paths
 194              $obd = ini_get('open_basedir');
 195  
 196              // If open_basedir is set we need to get the open_basedir that the path is in
 197              if ($obd != null)
 198              {
 199                  if (JPATH_ISWIN) {
 200                      $obdSeparator = ";";
 201                  } else {
 202                      $obdSeparator = ":";
 203                  }
 204                  // Create the array of open_basedir paths
 205                  $obdArray = explode($obdSeparator, $obd);
 206                  $inBaseDir = false;
 207                  // Iterate through open_basedir paths looking for a match
 208                  foreach ($obdArray as $test) {
 209                      $test = JPath::clean($test);
 210                      if (strpos($path, $test) === 0) {
 211                          $obdpath = $test;
 212                          $inBaseDir = true;
 213                          break;
 214                      }
 215                  }
 216                  if ($inBaseDir == false) {
 217                      // Return false for JFolder::create because the path to be created is not in open_basedir
 218                      JError::raiseWarning(
 219                          'SOME_ERROR_CODE',
 220                          'JFolder::create: ' . JText::_('Path not in open_basedir paths')
 221                      );
 222                      return false;
 223                  }
 224              }
 225  
 226              // First set umask
 227              $origmask = @umask(0);
 228  
 229              // Create the path
 230              if (!$ret = @mkdir($path, $mode)) {
 231                  @umask($origmask);
 232                  JError::raiseWarning(
 233                      'SOME_ERROR_CODE',
 234                      'JFolder::create: ' . JText::_('Could not create directory'),
 235                      'Path: ' . $path
 236                  );
 237                  return false;
 238              }
 239  
 240              // Reset umask
 241              @umask($origmask);
 242          }
 243          return $ret;
 244      }
 245  
 246      /**
 247       * Delete a folder.
 248       *
 249       * @param string The path to the folder to delete.
 250       * @return boolean True on success.
 251       * @since 1.5
 252       */
 253  	function delete($path)
 254      {
 255          // Sanity check
 256          if (!$path) {
 257              // Bad programmer! Bad Bad programmer!
 258              JError::raiseWarning(500, 'JFolder::delete: ' . JText::_('Attempt to delete base directory') );
 259              return false;
 260          }
 261  
 262          // Initialize variables
 263          jimport('joomla.client.helper');
 264          $ftpOptions = JClientHelper::getCredentials('ftp');
 265  
 266          // Check to make sure the path valid and clean
 267          $path = JPath::clean($path);
 268  
 269          // Is this really a folder?
 270          if (!is_dir($path)) {
 271              JError::raiseWarning(21, 'JFolder::delete: ' . JText::_('Path is not a folder'), 'Path: ' . $path);
 272              return false;
 273          }
 274  
 275          // Remove all the files in folder if they exist
 276          $files = JFolder::files($path, '.', false, true, array());
 277          if (!empty($files)) {
 278              jimport('joomla.filesystem.file');
 279              if (JFile::delete($files) !== true) {
 280                  // JFile::delete throws an error
 281                  return false;
 282              }
 283          }
 284  
 285          // Remove sub-folders of folder
 286          $folders = JFolder::folders($path, '.', false, true, array());
 287          foreach ($folders as $folder) {
 288              if (is_link($folder)) {
 289                  // Don't descend into linked directories, just delete the link.
 290                  jimport('joomla.filesystem.file');
 291                  if (JFile::delete($folder) !== true) {
 292                      // JFile::delete throws an error
 293                      return false;
 294                  }
 295              } elseif (JFolder::delete($folder) !== true) {
 296                  // JFolder::delete throws an error
 297                  return false;
 298              }
 299          }
 300  
 301          if ($ftpOptions['enabled'] == 1) {
 302              // Connect the FTP client
 303              jimport('joomla.client.ftp');
 304              $ftp = &JFTP::getInstance(
 305                  $ftpOptions['host'], $ftpOptions['port'], null,
 306                  $ftpOptions['user'], $ftpOptions['pass']
 307              );
 308          }
 309  
 310          // In case of restricted permissions we zap it one way or the other
 311          // as long as the owner is either the webserver or the ftp
 312          if (@rmdir($path)) {
 313              $ret = true;
 314          } elseif ($ftpOptions['enabled'] == 1) {
 315              // Translate path and delete
 316              $path = JPath::clean(str_replace(JPATH_ROOT, $ftpOptions['root'], $path), '/');
 317              // FTP connector throws an error
 318              $ret = $ftp->delete($path);
 319          } else {
 320              JError::raiseWarning(
 321                  'SOME_ERROR_CODE',
 322                  'JFolder::delete: ' . JText::_('Could not delete folder'),
 323                  'Path: ' . $path
 324              );
 325              $ret = false;
 326          }
 327          return $ret;
 328      }
 329  
 330      /**
 331       * Moves a folder.
 332       *
 333       * @param string The path to the source folder.
 334       * @param string The path to the destination folder.
 335       * @param string An optional base path to prefix to the file names.
 336       * @return mixed Error message on false or boolean true on success.
 337       * @since 1.5
 338       */
 339  	function move($src, $dest, $path = '')
 340      {
 341          // Initialize variables
 342          jimport('joomla.client.helper');
 343          $ftpOptions = JClientHelper::getCredentials('ftp');
 344  
 345          if ($path) {
 346              $src = JPath::clean($path . DS . $src);
 347              $dest = JPath::clean($path . DS . $dest);
 348          }
 349  
 350          if (!JFolder::exists($src) && !is_writable($src)) {
 351              return JText::_('Cannot find source folder');
 352          }
 353          if (JFolder::exists($dest)) {
 354              return JText::_('Folder already exists');
 355          }
 356  
 357          if ($ftpOptions['enabled'] == 1) {
 358              // Connect the FTP client
 359              jimport('joomla.client.ftp');
 360              $ftp = &JFTP::getInstance(
 361                  $ftpOptions['host'], $ftpOptions['port'], null,
 362                  $ftpOptions['user'], $ftpOptions['pass']
 363              );
 364  
 365              //Translate path for the FTP account
 366              $src = JPath::clean(str_replace(JPATH_ROOT, $ftpOptions['root'], $src), '/');
 367              $dest = JPath::clean(str_replace(JPATH_ROOT, $ftpOptions['root'], $dest), '/');
 368  
 369              // Use FTP rename to simulate move
 370              if (!$ftp->rename($src, $dest)) {
 371                  return JText::_('Rename failed');
 372              }
 373              $ret = true;
 374          } else {
 375              if (!@rename($src, $dest)) {
 376                  return JText::_('Rename failed');
 377              }
 378              $ret = true;
 379          }
 380          return $ret;
 381      }
 382  
 383      /**
 384       * Wrapper for the standard file_exists function
 385       *
 386       * @param string Folder name relative to installation dir
 387       * @return boolean True if path is a folder
 388       * @since 1.5
 389       */
 390  	function exists($path)
 391      {
 392          return is_dir(JPath::clean($path));
 393      }
 394  
 395      /**
 396       * Utility function to read the files in a folder.
 397       *
 398       * @param    string    The path of the folder to read.
 399       * @param    string    A filter for file names.
 400       * @param    mixed    True to recursively search into sub-folders, or an
 401       * integer to specify the maximum depth.
 402       * @param    boolean    True to return the full path to the file.
 403       * @param    array    Array with names of files which should not be shown in
 404       * the result.
 405       * @return    array    Files in the given folder.
 406       * @since 1.5
 407       */
 408  	function files($path, $filter = '.', $recurse = false, $fullpath = false, $exclude = array('.svn', 'CVS'))
 409      {
 410          // Initialize variables
 411          $arr = array();
 412  
 413          // Check to make sure the path valid and clean
 414          $path = JPath::clean($path);
 415  
 416          // Is the path a folder?
 417          if (!is_dir($path)) {
 418              JError::raiseWarning(21, 'JFolder::files: ' . JText::_('Path is not a folder'), 'Path: ' . $path);
 419              return false;
 420          }
 421  
 422          // read the source directory
 423          $handle = opendir($path);
 424          while (($file = readdir($handle)) !== false)
 425          {
 426              if (($file != '.') && ($file != '..') && (!in_array($file, $exclude))) {
 427                  $dir = $path . DS . $file;
 428                  $isDir = is_dir($dir);
 429                  if ($isDir) {
 430                      if ($recurse) {
 431                          if (is_integer($recurse)) {
 432                              $arr2 = JFolder::files($dir, $filter, $recurse - 1, $fullpath);
 433                          } else {
 434                              $arr2 = JFolder::files($dir, $filter, $recurse, $fullpath);
 435                          }
 436                          
 437                          $arr = array_merge($arr, $arr2);
 438                      }
 439                  } else {
 440                      if (preg_match("/$filter/", $file)) {
 441                          if ($fullpath) {
 442                              $arr[] = $path . DS . $file;
 443                          } else {
 444                              $arr[] = $file;
 445                          }
 446                      }
 447                  }
 448              }
 449          }
 450          closedir($handle);
 451  
 452          asort($arr);
 453          return $arr;
 454      }
 455  
 456      /**
 457       * Utility function to read the folders in a folder.
 458       *
 459       * @param    string    The path of the folder to read.
 460       * @param    string    A filter for folder names.
 461       * @param    mixed    True to recursively search into sub-folders, or an
 462       * integer to specify the maximum depth.
 463       * @param    boolean    True to return the full path to the folders.
 464       * @param    array    Array with names of folders which should not be shown in
 465       * the result.
 466       * @return    array    Folders in the given folder.
 467       * @since 1.5
 468       */
 469  	function folders($path, $filter = '.', $recurse = false, $fullpath = false, $exclude = array('.svn', 'CVS'))
 470      {
 471          // Initialize variables
 472          $arr = array();
 473  
 474          // Check to make sure the path valid and clean
 475          $path = JPath::clean($path);
 476  
 477          // Is the path a folder?
 478          if (!is_dir($path)) {
 479              JError::raiseWarning(21, 'JFolder::folder: ' . JText::_('Path is not a folder'), 'Path: ' . $path);
 480              return false;
 481          }
 482  
 483          // read the source directory
 484          $handle = opendir($path);
 485          while (($file = readdir($handle)) !== false)
 486          {
 487              if (($file != '.') && ($file != '..') && (!in_array($file, $exclude))) {
 488                  $dir = $path . DS . $file;
 489                  $isDir = is_dir($dir);
 490                  if ($isDir) {
 491                      // Removes filtered directories
 492                      if (preg_match("/$filter/", $file)) {
 493                          if ($fullpath) {
 494                              $arr[] = $dir;
 495                          } else {
 496                              $arr[] = $file;
 497                          }
 498                      }
 499                      if ($recurse) {
 500                          if (is_integer($recurse)) {
 501                              $arr2 = JFolder::folders($dir, $filter, $recurse - 1, $fullpath);
 502                          } else {
 503                              $arr2 = JFolder::folders($dir, $filter, $recurse, $fullpath);
 504                          }
 505                          
 506                          $arr = array_merge($arr, $arr2);
 507                      }
 508                  }
 509              }
 510          }
 511          closedir($handle);
 512  
 513          asort($arr);
 514          return $arr;
 515      }
 516  
 517      /**
 518       * Lists folder in format suitable for tree display.
 519       *
 520       * @access    public
 521       * @param    string    The path of the folder to read.
 522       * @param    string    A filter for folder names.
 523       * @param    integer    The maximum number of levels to recursively read,
 524       * defaults to three.
 525       * @param    integer    The current level, optional.
 526       * @param    integer    Unique identifier of the parent folder, if any.
 527       * @return    array    Folders in the given folder.
 528       * @since    1.5
 529       */
 530  	function listFolderTree($path, $filter, $maxLevel = 3, $level = 0, $parent = 0)
 531      {
 532          $dirs = array ();
 533          if ($level == 0) {
 534              $GLOBALS['_JFolder_folder_tree_index'] = 0;
 535          }
 536          if ($level < $maxLevel) {
 537              $folders = JFolder::folders($path, $filter);
 538              // first path, index foldernames
 539              foreach ($folders as $name) {
 540                  $id = ++$GLOBALS['_JFolder_folder_tree_index'];
 541                  $fullName = JPath::clean($path . DS . $name);
 542                  $dirs[] = array(
 543                      'id' => $id,
 544                      'parent' => $parent,
 545                      'name' => $name,
 546                      'fullname' => $fullName,
 547                      'relname' => str_replace(JPATH_ROOT, '', $fullName)
 548                  );
 549                  $dirs2 = JFolder::listFolderTree($fullName, $filter, $maxLevel, $level + 1, $id);
 550                  $dirs = array_merge($dirs, $dirs2);
 551              }
 552          }
 553          return $dirs;
 554      }
 555  
 556      /**
 557       * Makes path name safe to use.
 558       *
 559       * @access    public
 560       * @param    string The full path to sanitise.
 561       * @return    string The sanitised string.
 562       * @since    1.5
 563       */
 564  	function makeSafe($path)
 565      {
 566          $ds = (DS == '\\') ? '\\' . DS : DS;
 567          $regex = array('#[^A-Za-z0-9:\_\-' . $ds . ' ]#');
 568          return preg_replace($regex, '', $path);
 569      }
 570  
 571  }


Generated: Wed Mar 28 15:54:07 2012 Cross-referenced by PHPXref 0.7.1