Support Joomla!

Joomla! 1.5 Documentation

Packages

Package: Joomla-Framework

Developer Network License

The Joomla! Developer Network content is © copyright 2006 by the individual contributors and can be used in accordance with the Creative Commons License, Attribution- NonCommercial- ShareAlike 2.5
Source code for file /joomla/filesystem/folder.php

Documentation is available at folder.php

  1. <?php
  2. /**
  3.  * @version        $Id: folder.php 6472 2007-02-03 10:47:26Z pasamio $
  4.  * @package        Joomla.Framework
  5.  * @subpackage    FileSystem
  6.  * @copyright    Copyright (C) 2005 - 2007 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.  * @author        Louis Landry <[email protected]>
  25.  * @package     Joomla.Framework
  26.  * @subpackage    FileSystem
  27.  * @since        1.5
  28.  */
  29. class JFolder
  30. {
  31.     /**
  32.      * Copies a folder
  33.      *
  34.      * @param    string    $src    The path to the source folder
  35.      * @param    string    $dest    The path to the destination folder
  36.      * @param    string    $path    An optional base path to prefix to the file names
  37.      * @param    boolean    $force    Optionally force folder/file overwrites
  38.      * @return    mixed    JError object on failure or boolean True on success
  39.      * @since    1.5
  40.      */
  41.     function copy($src, $dest, $path = '', $force = false)
  42.     {
  43.         // Initialize variables
  44.         jimport('joomla.client.helper');
  45.         $FTPOptions = JClientHelper::getCredentials('ftp');
  46.  
  47.         if ($path) {
  48.             $src = JPath::clean($path.DS.$src);
  49.             $dest = JPath::clean($path.DS.$dest);
  50.         }
  51.  
  52.         // Eliminate trailing directory separators, if any
  53.         $src = rtrim($src, DS);
  54.         $dest = rtrim($dest, DS);
  55.  
  56.         if (!JFolder::exists($src)) {
  57.             return JError::raiseError(-1, JText::_('Cannot find source folder'));
  58.         }
  59.         if (JFolder::exists($dest) && !$force) {
  60.             return JError::raiseError(-1, JText::_('Folder already exists'));
  61.         }
  62.  
  63.         // Make sure the destination exists
  64.         if (! JFolder::create($dest)) {
  65.             return JError::raiseError(-1, JText::_('Unable to create target folder'));
  66.         }
  67.  
  68.         if ($FTPOptions['enabled'] == 1) {
  69.             // Connect the FTP client
  70.             jimport('joomla.client.ftp');
  71.             $ftp = & JFTP::getInstance($FTPOptions['host'], $FTPOptions['port'], null, $FTPOptions['user'], $FTPOptions['pass']);
  72.  
  73.             if(! ($dh = @opendir($src))) {
  74.                 return JError::raiseError(-1, JText::_('Unable to open source folder'));
  75.             }
  76.             // Walk through the directory copying files and recursing into folders.
  77.             while (($file = readdir($dh)) !== false) {
  78.                 $sfid = $src . DS . $file;
  79.                 $dfid = $dest . DS . $file;
  80.                 switch (filetype($sfid)) {
  81.                     case 'dir':
  82.                         if ($file != '.' && $file != '..') {
  83.                             $ret = JFolder::copy($sfid, $dfid, null, $force);
  84.                             if ($ret !== true) {
  85.                                 return $ret;
  86.                             }
  87.                         }
  88.                         break;
  89.  
  90.                     case 'file':
  91.                         //Translate path for the FTP account
  92.                         $dfid = JPath::clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $dfid), '/');
  93.                         if (! $ftp->store($sfid, $dfid)) {
  94.                             return JError::raiseError(-1, JText::_('Copy failed'));
  95.                         }
  96.                         break;
  97.                 }
  98.             }
  99.         } else {
  100.             if(! ($dh = @opendir($src))) {
  101.                 return JError::raiseError(-1, JText::_('Unable to open source folder'));
  102.             }
  103.             // Walk through the directory copying files and recursing into folders.
  104.             while (($file = readdir($dh)) !== false) {
  105.                 $sfid = $src.DS.$file;
  106.                 $dfid = $dest.DS.$file;
  107.                 switch (filetype($sfid)) {
  108.                     case 'dir':
  109.                         if ($file != '.' && $file != '..') {
  110.                             $ret = JFolder::copy($sfid, $dfid, null, $force);
  111.                             if ($ret !== true) {
  112.                                 return $ret;
  113.                             }
  114.                         }
  115.                         break;
  116.  
  117.                     case 'file':
  118.                         if (!@ copy($sfid, $dfid)) {
  119.                             return JError::raiseError(-1, JText::_('Copy failed'));
  120.                         }
  121.                         break;
  122.                 }
  123.             }
  124.         }
  125.         return true;
  126.     }
  127.  
  128.     /**
  129.      * Create a folder -- and all necessary parent folders
  130.      *
  131.      * @param string $path A path to create from the base path
  132.      * @param int $mode Directory permissions to set for folders created
  133.      * @return boolean True if successful
  134.      * @since 1.5
  135.      */
  136.     function create($path = '', $mode = 0755)
  137.     {
  138.         // Initialize variables
  139.         jimport('joomla.client.helper');
  140.         $FTPOptions = JClientHelper::getCredentials('ftp');
  141.         static $nested = 0;
  142.  
  143.         // Check to make sure the path valid and clean
  144.                 $path = JPath::clean($path);
  145.  
  146.         // Check if parent dir exists
  147.                 $parent = dirname($path);
  148.         if (!JFolder::exists($parent)) {
  149.             // Prevent infinite loops!
  150.                         $nested++;
  151.             if (($nested > 20) || ($parent == $path)) {
  152.                 JError::raiseWarning('SOME_ERROR_CODE', 'JFolder::create: '.JText::_('Infinite loop detected'));
  153.                 $nested--;
  154.                 return false;
  155.             }
  156.  
  157.             // Create the parent directory
  158.             if (JFolder::create($parent, $mode) !== true) {
  159.                 // JFolder::create throws an error
  160.                 $nested--;
  161.                 return false;
  162.             }
  163.  
  164.             // OK, parent directory has been created
  165.             $nested--;
  166.         }
  167.  
  168.         // Check if dir already exists
  169.                 if (JFolder::exists($path)) {
  170.             return true;
  171.         }
  172.  
  173.         // Check for safe mode
  174.                 if ($FTPOptions['enabled'] == 1) {
  175.             // Connect the FTP client
  176.                         jimport('joomla.client.ftp');
  177.             $ftp = & JFTP::getInstance($FTPOptions['host'], $FTPOptions['port'], null, $FTPOptions['user'], $FTPOptions['pass']);
  178.  
  179.             // Translate path to FTP path
  180.                         $path = JPath::clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $path), '/');
  181.             $ret = $ftp->mkdir($path);
  182.             $ftp->chmod($path, $mode);
  183.         }
  184.         else
  185.         {
  186.             // We need to get and explode the open_basedir paths
  187.                         $obd = ini_get('open_basedir');
  188.  
  189.             // If open_basedir is set we need to get the open_basedir that the path is in
  190.                         if ($obd != null)
  191.             {
  192.                 if (JPATH_ISWIN) {
  193.                     $obdSeparator = ";";
  194.                 } else {
  195.                     $obdSeparator = ":";
  196.                 }
  197.                 // Create the array of open_basedir paths
  198.                                 $obdArray = explode($obdSeparator, $obd);
  199.                 $inOBD = false;
  200.                 // Iterate through open_basedir paths looking for a match
  201.                                 foreach ($obdArray as $test) {
  202.                     $test = JPath::clean($test);
  203.                     if (strpos($path, $test) === 0) {
  204.                         $obdpath = $test;
  205.                         $inOBD = true;
  206.                         break;
  207.                     }
  208.                 }
  209.                 if ($inOBD == false) {
  210.                     // Return false for JFolder::create because the path to be created is not in open_basedir
  211.                                         JError::raiseWarning('SOME_ERROR_CODE', 'JFolder::create: '.JText::_('Path not in open_basedir paths'));
  212.                     return false;
  213.                 }
  214.             }
  215.  
  216.             // First set umask
  217.                         $origmask = @ umask(0);
  218.  
  219.             // Create the path
  220.                         if (!$ret = @mkdir($path, $mode)) {
  221.                 @ umask($origmask);
  222.                 JError::raiseWarning('SOME_ERROR_CODE', 'JFolder::create: '.JText::_('Could not create directory'), 'Path: '.$path);
  223.                 return false;
  224.             }
  225.  
  226.             // Reset umask
  227.                         @ umask($origmask);
  228.         }
  229.         return $ret;
  230.     }
  231.  
  232.     /**
  233.      * Delete a folder
  234.      *
  235.      * @param string $path The path to the folder to delete
  236.      * @return boolean True on success
  237.      * @since 1.5
  238.      */
  239.     function delete($path)
  240.     {
  241.         // Initialize variables
  242.         jimport('joomla.client.helper');
  243.         $FTPOptions = JClientHelper::getCredentials('ftp');
  244.  
  245.         // Check to make sure the path valid and clean
  246.         $path = JPath::clean($path);
  247.  
  248.         // Is this really a folder?
  249.         if (!is_dir($path)) {
  250.             JError::raiseWarning(21, 'JFolder::delete: '.JText::_('Path is not a folder').' '.$path);
  251.             return false;
  252.         }
  253.  
  254.         // Remove all the files in folder if they exist
  255.         $files = JFolder::files($path, '.', false, true);
  256.         if (count($files)) {
  257.             jimport('joomla.filesystem.file');
  258.             if (JFile::delete($files) !== true) {
  259.                 // JFile::delete throws an error
  260.                 return false;
  261.             }
  262.         }
  263.  
  264.         // Remove sub-folders of folder
  265.         $folders = JFolder::folders($path, '.', false, true);
  266.         foreach ($folders as $folder) {
  267.             if (JFolder::delete($folder) !== true) {
  268.                 // JFolder::delete throws an error
  269.                 return false;
  270.             }
  271.         }
  272.  
  273.         if ($FTPOptions['enabled'] == 1) {
  274.             // Connect the FTP client
  275.             jimport('joomla.client.ftp');
  276.             $ftp = & JFTP::getInstance($FTPOptions['host'], $FTPOptions['port'], null, $FTPOptions['user'], $FTPOptions['pass']);
  277.         }
  278.  
  279.         // In case of restricted permissions we zap it one way or the other
  280.         // as long as the owner is either the webserver or the ftp
  281.         if (@rmdir($path)) {
  282.             $ret = true;
  283.         } elseif ($FTPOptions['enabled'] == 1) {
  284.             // Translate path and delete
  285.             $path = JPath::clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $path), '/');
  286.             // FTP connector throws an error
  287.             $ret = $ftp->delete($path);
  288.         } else {
  289.             JError::raiseWarning('SOME_ERROR_CODE', 'JFolder::delete: '.JText::_('Could not delete folder').' '.$path);
  290.             $ret = false;
  291.         }
  292.  
  293.         return $ret;
  294.     }
  295.  
  296.     /**
  297.      * Moves a folder
  298.      *
  299.      * @param string $src The path to the source folder
  300.      * @param string $dest The path to the destination folder
  301.      * @param string $path An optional base path to prefix to the file names
  302.      * @return mixed Error message on false or boolean True on success
  303.      * @since 1.5
  304.      */
  305.     function move($src, $dest, $path = '')
  306.     {
  307.         // Initialize variables
  308.         jimport('joomla.client.helper');
  309.         $FTPOptions = JClientHelper::getCredentials('ftp');
  310.  
  311.         if ($path) {
  312.             $src = JPath::clean($path.DS.$src);
  313.             $dest = JPath::clean($path.DS.$dest);
  314.         }
  315.  
  316.         if (!JFolder::exists($src) && !is_writable($src)) {
  317.             return JText::_('Cannot find source folder');
  318.         }
  319.         if (JFolder::exists($dest)) {
  320.             return JText::_('Folder already exists');
  321.         }
  322.  
  323.         if ($FTPOptions['enabled'] == 1) {
  324.             // Connect the FTP client
  325.             jimport('joomla.client.ftp');
  326.             $ftp = & JFTP::getInstance($FTPOptions['host'], $FTPOptions['port'], null, $FTPOptions['user'], $FTPOptions['pass']);
  327.  
  328.             //Translate path for the FTP account
  329.             $src = JPath::clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $src), '/');
  330.             $dest = JPath::clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $dest), '/');
  331.  
  332.             // Use FTP rename to simulate move
  333.             if (!$ftp->rename($src, $dest)) {
  334.                 return JText::_('Rename failed');
  335.             }
  336.             $ret = true;
  337.         } else {
  338.             if (!@ rename($src, $dest)) {
  339.                 return JText::_('Rename failed');
  340.             }
  341.             $ret = true;
  342.         }
  343.         return $ret;
  344.     }
  345.  
  346.     /**
  347.      * Wrapper for the standard file_exists function
  348.      *
  349.      * @param string $path Folder name relative to installation dir
  350.      * @return boolean True if path is a folder
  351.      * @since 1.5
  352.      */
  353.     function exists($path)
  354.     {
  355.         return is_dir(JPath::clean($path));
  356.     }
  357.  
  358.     /**
  359.      * Utility function to read the files in a folder
  360.      *
  361.      * @param    string    $path        The path of the folder to read
  362.      * @param    string    $filter        A filter for file names
  363.      * @param    boolean    $recurse    True to recursively search into sub-folders
  364.      * @param    boolean    $fullpath    True to return the full path to the file
  365.      * @return    array    Files in the given folder
  366.      * @since 1.5
  367.      */
  368.     function files($path, $filter = '.', $recurse = false, $fullpath = false)
  369.     {
  370.         // Initialize variables
  371.         $arr = array ();
  372.  
  373.         // Check to make sure the path valid and clean
  374.         $path = JPath::clean($path);
  375.  
  376.         // Is the path a folder?
  377.         if (!is_dir($path)) {
  378.             JError::raiseWarning(21, 'JFolder::files: '.JText::_('Path is not a folder').' '.$path);
  379.             return false;
  380.         }
  381.  
  382.         // read the source directory
  383.         $handle = opendir($path);
  384.         while ($file = readdir($handle)) {
  385.             $dir = $path.DS.$file;
  386.             $isDir = is_dir($dir);
  387.             if (($file != '.') && ($file != '..') && ($file != '.svn') && ($file != 'CVS')) {
  388.                 if ($isDir) {
  389.                     if ($recurse) {
  390.                         $arr2 = JFolder::files($dir, $filter, $recurse, $fullpath);
  391.                         $arr = array_merge($arr, $arr2);
  392.                     }
  393.                 } else {
  394.                     if (preg_match("/$filter/", $file)) {
  395.                         if ($fullpath) {
  396.                             $arr[] = $path.DS.$file;
  397.                         } else {
  398.                             $arr[] = $file;
  399.                         }
  400.                     }
  401.                 }
  402.             }
  403.         }
  404.         closedir($handle);
  405.  
  406.         asort($arr);
  407.         return $arr;
  408.     }
  409.  
  410.     /**
  411.      * Utility function to read the folders in a folder
  412.      *
  413.      * @param    string    $path        The path of the folder to read
  414.      * @param    string    $filter        A filter for folder names
  415.      * @param    boolean    $recurse    True to recursively search into sub-folders
  416.      * @param    boolean    $fullpath    True to return the full path to the folders
  417.      * @return    array    Folders in the given folder
  418.      * @since 1.5
  419.      */
  420.     function folders($path, $filter = '.', $recurse = false, $fullpath = false)
  421.     {
  422.         // Initialize variables
  423.         $arr = array ();
  424.  
  425.         // Check to make sure the path valid and clean
  426.         $path = JPath::clean($path);
  427.  
  428.         // Is the path a folder?
  429.         if (!is_dir($path)) {
  430.             JError::raiseWarning(21, 'JFolder::folder: '.JText::_('Path is not a folder').' '.$path);
  431.             return false;
  432.         }
  433.  
  434.         // read the source directory
  435.         $handle = opendir($path);
  436.         while ($file = readdir($handle)) {
  437.             $dir = $path.DS.$file;
  438.             $isDir = is_dir($dir);
  439.             if (($file != '.') && ($file != '..') && ($file != '.svn') && ($file != 'CVS') && $isDir) {
  440.                 // removes SVN directores from list
  441.                 if (preg_match("/$filter/", $file)) {
  442.                     if ($fullpath) {
  443.                         $arr[] = $dir;
  444.                     } else {
  445.                         $arr[] = $file;
  446.                     }
  447.                 }
  448.                 if ($recurse) {
  449.                     $arr2 = JFolder::folders($dir, $filter, $recurse, $fullpath);
  450.                     $arr = array_merge($arr, $arr2);
  451.                 }
  452.             }
  453.         }
  454.         closedir($handle);
  455.  
  456.         asort($arr);
  457.         return $arr;
  458.     }
  459.  
  460.     /**
  461.      * Lists folder in format suitable for tree display
  462.      */
  463.     function listFolderTree($path, $filter, $maxLevel = 3, $level = 0, $parent = 0)
  464.     {
  465.         $dirs = array ();
  466.         if ($level == 0) {
  467.             $GLOBALS['_JFolder_folder_tree_index'] = 0;
  468.         }
  469.         if ($level < $maxLevel) {
  470.             $folders = JFolder::folders($path, $filter);
  471.             // first path, index foldernames
  472.             for ($i = 0, $n = count($folders); $i < $n; $i ++) {
  473.                 $id = ++ $GLOBALS['_JFolder_folder_tree_index'];
  474.                 $name = $folders[$i];
  475.                 $fullName = JPath::clean($path.DS.$name);
  476.                 $dirs[] = array ('id' => $id, 'parent' => $parent, 'name' => $name, 'fullname' => $fullName, 'relname' => str_replace(JPATH_ROOT, '', $fullName));
  477.                 $dirs2 = JFolder::listFolderTree($fullName, $filter, $maxLevel, $level +1, $id);
  478.                 $dirs = array_merge($dirs, $dirs2);
  479.             }
  480.         }
  481.         return $dirs;
  482.     }
  483. }
  484. ?>

Documentation generated on Mon, 05 Mar 2007 20:59:32 +0000 by phpDocumentor 1.3.1