Overview

Packages

  • application
    • commands
    • components
      • actions
      • filters
      • leftWidget
      • permissions
      • sortableWidget
      • util
      • webupdater
      • x2flow
        • actions
        • triggers
      • X2GridView
      • X2Settings
    • controllers
    • models
      • embedded
    • modules
      • accounts
        • controllers
        • models
      • actions
        • controllers
        • models
      • calendar
        • controllers
        • models
      • charts
        • models
      • contacts
        • controllers
        • models
      • docs
        • components
        • controllers
        • models
      • groups
        • controllers
        • models
      • marketing
        • components
        • controllers
        • models
      • media
        • controllers
        • models
      • mobile
        • components
      • opportunities
        • controllers
        • models
      • products
        • controllers
        • models
      • quotes
        • controllers
        • models
      • services
        • controllers
        • models
      • template
        • models
      • users
        • controllers
        • models
      • workflow
        • controllers
        • models
      • x2Leads
        • controllers
        • models
  • Net
  • None
  • PHP
  • system
    • base
    • caching
      • dependencies
    • collections
    • console
    • db
      • ar
      • schema
        • cubrid
        • mssql
        • mysql
        • oci
        • pgsql
        • sqlite
    • i18n
      • gettext
    • logging
    • test
    • utils
    • validators
    • web
      • actions
      • auth
      • filters
      • form
      • helpers
      • renderers
      • services
      • widgets
        • captcha
        • pagers
  • Text
    • Highlighter
  • zii
    • behaviors
    • widgets
      • grid
      • jui

Classes

  • CDateTimeParser
  • CFileHelper
  • CFormatter
  • CLocalizedFormatter
  • CMarkdownParser
  • CPasswordHelper
  • CPropertyValue
  • CTimestamp
  • CVarDumper
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * CFileHelper class file.
  4:  *
  5:  * @author Qiang Xue <qiang.xue@gmail.com>
  6:  * @link http://www.yiiframework.com/
  7:  * @copyright 2008-2013 Yii Software LLC
  8:  * @license http://www.yiiframework.com/license/
  9:  */
 10: 
 11: /**
 12:  * CFileHelper provides a set of helper methods for common file system operations.
 13:  *
 14:  * @author Qiang Xue <qiang.xue@gmail.com>
 15:  * @package system.utils
 16:  * @since 1.0
 17:  */
 18: class CFileHelper
 19: {
 20:     /**
 21:      * Returns the extension name of a file path.
 22:      * For example, the path "path/to/something.php" would return "php".
 23:      * @param string $path the file path
 24:      * @return string the extension name without the dot character.
 25:      * @since 1.1.2
 26:      */
 27:     public static function getExtension($path)
 28:     {
 29:         return pathinfo($path,PATHINFO_EXTENSION);
 30:     }
 31: 
 32:     /**
 33:      * Copies a directory recursively as another.
 34:      * If the destination directory does not exist, it will be created recursively.
 35:      * @param string $src the source directory
 36:      * @param string $dst the destination directory
 37:      * @param array $options options for directory copy. Valid options are:
 38:      * <ul>
 39:      * <li>fileTypes: array, list of file name suffix (without dot). Only files with these suffixes will be copied.</li>
 40:      * <li>exclude: array, list of directory and file exclusions. Each exclusion can be either a name or a path.
 41:      * If a file or directory name or path matches the exclusion, it will not be copied. For example, an exclusion of
 42:      * '.svn' will exclude all files and directories whose name is '.svn'. And an exclusion of '/a/b' will exclude
 43:      * file or directory '$src/a/b'. Note, that '/' should be used as separator regardless of the value of the DIRECTORY_SEPARATOR constant.
 44:      * </li>
 45:      * <li>level: integer, recursion depth, default=-1.
 46:      * Level -1 means copying all directories and files under the directory;
 47:      * Level 0 means copying only the files DIRECTLY under the directory;
 48:      * level N means copying those directories that are within N levels.
 49:      * </li>
 50:      * <li>newDirMode - the permission to be set for newly copied directories (defaults to 0777);</li>
 51:      * <li>newFileMode - the permission to be set for newly copied files (defaults to the current environment setting).</li>
 52:      * </ul>
 53:      */
 54:     public static function copyDirectory($src,$dst,$options=array())
 55:     {
 56:         $fileTypes=array();
 57:         $exclude=array();
 58:         $level=-1;
 59:         extract($options);
 60:         if(!is_dir($dst))
 61:             self::createDirectory($dst,isset($options['newDirMode'])?$options['newDirMode']:null,true);
 62: 
 63:         self::copyDirectoryRecursive($src,$dst,'',$fileTypes,$exclude,$level,$options);
 64:     }
 65: 
 66:     /**
 67:      * Removes a directory recursively.
 68:      * @param string $directory to be deleted recursively.
 69:      * @param array $options for the directory removal. Valid options are:
 70:      * <ul>
 71:      * <li>traverseSymlinks: boolean, whether symlinks to the directories should be traversed too.
 72:      * Defaults to `false`, meaning that the content of the symlinked directory would not be deleted.
 73:      * Only symlink would be removed in that default case.</li>
 74:      * </ul>
 75:      * Note, options parameter is available since 1.1.16
 76:      * @since 1.1.14
 77:      */
 78:     public static function removeDirectory($directory,$options=array())
 79:     {
 80:         if(!isset($options['traverseSymlinks']))
 81:             $options['traverseSymlinks']=false;
 82:         $items=glob($directory.DIRECTORY_SEPARATOR.'{,.}*',GLOB_MARK | GLOB_BRACE);
 83:         foreach($items as $item)
 84:         {
 85:             if(basename($item)=='.' || basename($item)=='..')
 86:                 continue;
 87:             if(substr($item,-1)==DIRECTORY_SEPARATOR)
 88:             {
 89:                 if(!$options['traverseSymlinks'] && is_link(rtrim($item,DIRECTORY_SEPARATOR)))
 90:                     unlink(rtrim($item,DIRECTORY_SEPARATOR));
 91:                 else
 92:                     self::removeDirectory($item,$options);
 93:             }
 94:             else
 95:                 unlink($item);
 96:         }
 97:         if(is_dir($directory=rtrim($directory,'\\/')))
 98:         {
 99:             if(is_link($directory))
100:                 unlink($directory);
101:             else
102:                 rmdir($directory);
103:         }
104:     }
105: 
106:     /**
107:      * Returns the files found under the specified directory and subdirectories.
108:      * @param string $dir the directory under which the files will be looked for
109:      * @param array $options options for file searching. Valid options are:
110:      * <ul>
111:      * <li>fileTypes: array, list of file name suffix (without dot). Only files with these suffixes will be returned.</li>
112:      * <li>exclude: array, list of directory and file exclusions. Each exclusion can be either a name or a path.
113:      * If a file or directory name or path matches the exclusion, it will not be copied. For example, an exclusion of
114:      * '.svn' will exclude all files and directories whose name is '.svn'. And an exclusion of '/a/b' will exclude
115:      * file or directory '$src/a/b'. Note, that '/' should be used as separator regardless of the value of the DIRECTORY_SEPARATOR constant.
116:      * </li>
117:      * <li>level: integer, recursion depth, default=-1.
118:      * Level -1 means searching for all directories and files under the directory;
119:      * Level 0 means searching for only the files DIRECTLY under the directory;
120:      * level N means searching for those directories that are within N levels.
121:      * </li>
122:      * <li>absolutePaths: boolean, whether to return absolute paths or relative ones, defaults to true.</li>
123:      * </ul>
124:      * @return array files found under the directory. The file list is sorted.
125:      */
126:     public static function findFiles($dir,$options=array())
127:     {
128:         $fileTypes=array();
129:         $exclude=array();
130:         $level=-1;
131:         $absolutePaths=true;
132:         extract($options);
133:         $list=self::findFilesRecursive($dir,'',$fileTypes,$exclude,$level,$absolutePaths);
134:         sort($list);
135:         return $list;
136:     }
137: 
138:     /**
139:      * Copies a directory.
140:      * This method is mainly used by {@link copyDirectory}.
141:      * @param string $src the source directory
142:      * @param string $dst the destination directory
143:      * @param string $base the path relative to the original source directory
144:      * @param array $fileTypes list of file name suffix (without dot). Only files with these suffixes will be copied.
145:      * @param array $exclude list of directory and file exclusions. Each exclusion can be either a name or a path.
146:      * If a file or directory name or path matches the exclusion, it will not be copied. For example, an exclusion of
147:      * '.svn' will exclude all files and directories whose name is '.svn'. And an exclusion of '/a/b' will exclude
148:      * file or directory '$src/a/b'. Note, that '/' should be used as separator regardless of the value of the DIRECTORY_SEPARATOR constant.
149:      * @param integer $level recursion depth. It defaults to -1.
150:      * Level -1 means copying all directories and files under the directory;
151:      * Level 0 means copying only the files DIRECTLY under the directory;
152:      * level N means copying those directories that are within N levels.
153:      * @param array $options additional options. The following options are supported:
154:      * newDirMode - the permission to be set for newly copied directories (defaults to 0777);
155:      * newFileMode - the permission to be set for newly copied files (defaults to the current environment setting).
156:      */
157:     protected static function copyDirectoryRecursive($src,$dst,$base,$fileTypes,$exclude,$level,$options)
158:     {
159:         if(!is_dir($dst))
160:             self::createDirectory($dst,isset($options['newDirMode'])?$options['newDirMode']:null,false);
161: 
162:         $folder=opendir($src);
163:         if($folder===false)
164:             throw new Exception('Unable to open directory: ' . $src);
165:         while(($file=readdir($folder))!==false)
166:         {
167:             if($file==='.' || $file==='..')
168:                 continue;
169:             $path=$src.DIRECTORY_SEPARATOR.$file;
170:             $isFile=is_file($path);
171:             if(self::validatePath($base,$file,$isFile,$fileTypes,$exclude))
172:             {
173:                 if($isFile)
174:                 {
175:                     copy($path,$dst.DIRECTORY_SEPARATOR.$file);
176:                     if(isset($options['newFileMode']))
177:                         @chmod($dst.DIRECTORY_SEPARATOR.$file,$options['newFileMode']);
178:                 }
179:                 elseif($level)
180:                     self::copyDirectoryRecursive($path,$dst.DIRECTORY_SEPARATOR.$file,$base.'/'.$file,$fileTypes,$exclude,$level-1,$options);
181:             }
182:         }
183:         closedir($folder);
184:     }
185: 
186:     /**
187:      * Returns the files found under the specified directory and subdirectories.
188:      * This method is mainly used by {@link findFiles}.
189:      * @param string $dir the source directory
190:      * @param string $base the path relative to the original source directory
191:      * @param array $fileTypes list of file name suffix (without dot). Only files with these suffixes will be returned.
192:      * @param array $exclude list of directory and file exclusions. Each exclusion can be either a name or a path.
193:      * If a file or directory name or path matches the exclusion, it will not be copied. For example, an exclusion of
194:      * '.svn' will exclude all files and directories whose name is '.svn'. And an exclusion of '/a/b' will exclude
195:      * file or directory '$src/a/b'. Note, that '/' should be used as separator regardless of the value of the DIRECTORY_SEPARATOR constant.
196:      * @param integer $level recursion depth. It defaults to -1.
197:      * Level -1 means searching for all directories and files under the directory;
198:      * Level 0 means searching for only the files DIRECTLY under the directory;
199:      * level N means searching for those directories that are within N levels.
200:      * @param boolean $absolutePaths whether to return absolute paths or relative ones
201:      * @return array files found under the directory.
202:      */
203:     protected static function findFilesRecursive($dir,$base,$fileTypes,$exclude,$level,$absolutePaths)
204:     {
205:         $list=array();
206:         $handle=opendir($dir.$base);
207:         if($handle===false)
208:             throw new Exception('Unable to open directory: ' . $dir);
209:         while(($file=readdir($handle))!==false)
210:         {
211:             if($file==='.' || $file==='..')
212:                 continue;
213:             $path=substr($base.DIRECTORY_SEPARATOR.$file,1);
214:             $fullPath=$dir.DIRECTORY_SEPARATOR.$path;
215:             $isFile=is_file($fullPath);
216:             if(self::validatePath($base,$file,$isFile,$fileTypes,$exclude))
217:             {
218:                 if($isFile)
219:                     $list[]=$absolutePaths?$fullPath:$path;
220:                 elseif($level)
221:                     $list=array_merge($list,self::findFilesRecursive($dir,$base.'/'.$file,$fileTypes,$exclude,$level-1,$absolutePaths));
222:             }
223:         }
224:         closedir($handle);
225:         return $list;
226:     }
227: 
228:     /**
229:      * Validates a file or directory.
230:      * @param string $base the path relative to the original source directory
231:      * @param string $file the file or directory name
232:      * @param boolean $isFile whether this is a file
233:      * @param array $fileTypes list of valid file name suffixes (without dot).
234:      * @param array $exclude list of directory and file exclusions. Each exclusion can be either a name or a path.
235:      * If a file or directory name or path matches the exclusion, false will be returned. For example, an exclusion of
236:      * '.svn' will return false for all files and directories whose name is '.svn'. And an exclusion of '/a/b' will return false for
237:      * file or directory '$src/a/b'. Note, that '/' should be used as separator regardless of the value of the DIRECTORY_SEPARATOR constant.
238:      * @return boolean whether the file or directory is valid
239:      */
240:     protected static function validatePath($base,$file,$isFile,$fileTypes,$exclude)
241:     {
242:         foreach($exclude as $e)
243:         {
244:             if($file===$e || strpos($base.'/'.$file,$e)===0)
245:                 return false;
246:         }
247:         if(!$isFile || empty($fileTypes))
248:             return true;
249:         if(($type=self::getExtension($file))!=='')
250:             return in_array($type,$fileTypes);
251:         else
252:             return false;
253:     }
254: 
255:     /**
256:      * Determines the MIME type of the specified file.
257:      * This method will attempt the following approaches in order:
258:      * <ol>
259:      * <li>finfo</li>
260:      * <li>mime_content_type</li>
261:      * <li>{@link getMimeTypeByExtension}, when $checkExtension is set true.</li>
262:      * </ol>
263:      * @param string $file the file name.
264:      * @param string $magicFile name of a magic database file, usually something like /path/to/magic.mime.
265:      * This will be passed as the second parameter to {@link http://php.net/manual/en/function.finfo-open.php finfo_open}.
266:      * Magic file format described in {@link http://linux.die.net/man/5/magic man 5 magic}, note that this file does not
267:      * contain a standard PHP array as you might suppose. Specified magic file will be used only when fileinfo
268:      * PHP extension is available. This parameter has been available since version 1.1.3.
269:      * @param boolean $checkExtension whether to check the file extension in case the MIME type cannot be determined
270:      * based on finfo and mime_content_type. Defaults to true. This parameter has been available since version 1.1.4.
271:      * @return string the MIME type. Null is returned if the MIME type cannot be determined.
272:      */
273:     public static function getMimeType($file,$magicFile=null,$checkExtension=true)
274:     {
275:         if(function_exists('finfo_open'))
276:         {
277:             $options=defined('FILEINFO_MIME_TYPE') ? FILEINFO_MIME_TYPE : FILEINFO_MIME;
278:             $info=$magicFile===null ? finfo_open($options) : finfo_open($options,$magicFile);
279: 
280:             if($info && ($result=finfo_file($info,$file))!==false)
281:                 return $result;
282:         }
283: 
284:         if(function_exists('mime_content_type') && ($result=mime_content_type($file))!==false)
285:             return $result;
286: 
287:         return $checkExtension ? self::getMimeTypeByExtension($file) : null;
288:     }
289: 
290:     /**
291:      * Determines the MIME type based on the extension name of the specified file.
292:      * This method will use a local map between extension name and MIME type.
293:      * @param string $file the file name.
294:      * @param string $magicFile the path of the file that contains all available MIME type information.
295:      * If this is not set, the default 'system.utils.mimeTypes' file will be used.
296:      * This parameter has been available since version 1.1.3.
297:      * @return string the MIME type. Null is returned if the MIME type cannot be determined.
298:      */
299:     public static function getMimeTypeByExtension($file,$magicFile=null)
300:     {
301:         static $extensions,$customExtensions=array();
302:         if($magicFile===null && $extensions===null)
303:             $extensions=require(Yii::getPathOfAlias('system.utils.mimeTypes').'.php');
304:         elseif($magicFile!==null && !isset($customExtensions[$magicFile]))
305:             $customExtensions[$magicFile]=require($magicFile);
306:         if(($ext=self::getExtension($file))!=='')
307:         {
308:             $ext=strtolower($ext);
309:             if($magicFile===null && isset($extensions[$ext]))
310:                 return $extensions[$ext];
311:             elseif($magicFile!==null && isset($customExtensions[$magicFile][$ext]))
312:                 return $customExtensions[$magicFile][$ext];
313:         }
314:         return null;
315:     }
316: 
317:     /**
318:      * Determines the file extension name based on its MIME type.
319:      * This method will use a local map between MIME type and extension name.
320:      * @param string $file the file name.
321:      * @param string $magicFile the path of the file that contains all available extension information.
322:      * If this is not set, the default 'system.utils.fileExtensions' file will be used.
323:      * This parameter has been available since version 1.1.16.
324:      * @return string extension name. Null is returned if the extension cannot be determined.
325:      */
326:     public static function getExtensionByMimeType($file,$magicFile=null)
327:     {
328:         static $mimeTypes,$customMimeTypes=array();
329:         if($magicFile===null && $mimeTypes===null)
330:             $mimeTypes=require(Yii::getPathOfAlias('system.utils.fileExtensions').'.php');
331:         elseif($magicFile!==null && !isset($customMimeTypes[$magicFile]))
332:             $customMimeTypes[$magicFile]=require($magicFile);
333:         if(($mime=self::getMimeType($file))!==null)
334:         {
335:             $mime=strtolower($mime);
336:             if($magicFile===null && isset($mimeTypes[$mime]))
337:                 return $mimeTypes[$mime];
338:             elseif($magicFile!==null && isset($customMimeTypes[$magicFile][$mime]))
339:                 return $customMimeTypes[$magicFile][$mime];
340:         }
341:         return null;
342:     }
343: 
344:     /**
345:      * Shared environment safe version of mkdir. Supports recursive creation.
346:      * For avoidance of umask side-effects chmod is used.
347:      *
348:      * @param string $dst path to be created
349:      * @param integer $mode the permission to be set for newly created directories, if not set - 0777 will be used
350:      * @param boolean $recursive whether to create directory structure recursive if parent dirs do not exist
351:      * @return boolean result of mkdir
352:      * @see mkdir
353:      */
354:     public static function createDirectory($dst,$mode=null,$recursive=false)
355:     {
356:         if($mode===null)
357:             $mode=0777;
358:         $prevDir=dirname($dst);
359:         if($recursive && !is_dir($dst) && !is_dir($prevDir))
360:             self::createDirectory(dirname($dst),$mode,true);
361:         $res=mkdir($dst, $mode);
362:         @chmod($dst,$mode);
363:         return $res;
364:     }
365: }
366: 
API documentation generated by ApiGen 2.8.0