blob: 3fd6b82e10ff2e18591094fe05e15eca8fe0395b [file] [log] [blame]
Andrey Andreev8bf6bb62012-01-06 16:11:04 +02001<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
Derek Allard2067d1a2008-11-13 22:59:24 +00002/**
3 * CodeIgniter
4 *
Phil Sturgeon07c1ac82012-03-09 17:03:37 +00005 * An open source application development framework for PHP 5.2.4 or newer
Derek Allard2067d1a2008-11-13 22:59:24 +00006 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05007 * NOTICE OF LICENSE
Andrey Andreev8bf6bb62012-01-06 16:11:04 +02008 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05009 * Licensed under the Open Software License version 3.0
Andrey Andreev8bf6bb62012-01-06 16:11:04 +020010 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -050011 * This source file is subject to the Open Software License (OSL 3.0) that is
12 * bundled with this package in the files license.txt / license.rst. It is
13 * also available through the world wide web at this URL:
14 * http://opensource.org/licenses/OSL-3.0
15 * If you did not receive a copy of the license and are unable to obtain it
16 * through the world wide web, please send an email to
17 * licensing@ellislab.com so we can send you a copy immediately.
18 *
Derek Allard2067d1a2008-11-13 22:59:24 +000019 * @package CodeIgniter
Derek Jonesf4a4bd82011-10-20 12:18:42 -050020 * @author EllisLab Dev Team
Greg Aker0defe5d2012-01-01 18:46:41 -060021 * @copyright Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
Derek Jonesf4a4bd82011-10-20 12:18:42 -050022 * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
Derek Allard2067d1a2008-11-13 22:59:24 +000023 * @link http://codeigniter.com
24 * @since Version 1.0
25 * @filesource
26 */
27
28// ------------------------------------------------------------------------
29
30/**
31 * CodeIgniter File Helpers
32 *
33 * @package CodeIgniter
34 * @subpackage Helpers
35 * @category Helpers
Derek Jonesf4a4bd82011-10-20 12:18:42 -050036 * @author EllisLab Dev Team
Derek Jonesc37f0e12009-04-21 13:33:40 +000037 * @link http://codeigniter.com/user_guide/helpers/file_helpers.html
Derek Allard2067d1a2008-11-13 22:59:24 +000038 */
39
40// ------------------------------------------------------------------------
41
42/**
43 * Read File
44 *
45 * Opens the file specfied in the path and returns it as a string.
46 *
47 * @access public
48 * @param string path to file
49 * @return string
Barry Mienydd671972010-10-04 16:33:58 +020050 */
Derek Allard2067d1a2008-11-13 22:59:24 +000051if ( ! function_exists('read_file'))
52{
53 function read_file($file)
54 {
55 if ( ! file_exists($file))
56 {
57 return FALSE;
58 }
Barry Mienydd671972010-10-04 16:33:58 +020059
Derek Allard2067d1a2008-11-13 22:59:24 +000060 if (function_exists('file_get_contents'))
61 {
Barry Mienydd671972010-10-04 16:33:58 +020062 return file_get_contents($file);
Derek Allard2067d1a2008-11-13 22:59:24 +000063 }
64
65 if ( ! $fp = @fopen($file, FOPEN_READ))
66 {
67 return FALSE;
68 }
Barry Mienydd671972010-10-04 16:33:58 +020069
Derek Allard2067d1a2008-11-13 22:59:24 +000070 flock($fp, LOCK_SH);
Barry Mienydd671972010-10-04 16:33:58 +020071
Derek Allard2067d1a2008-11-13 22:59:24 +000072 $data = '';
73 if (filesize($file) > 0)
74 {
75 $data =& fread($fp, filesize($file));
76 }
77
78 flock($fp, LOCK_UN);
79 fclose($fp);
80
81 return $data;
82 }
83}
Barry Mienydd671972010-10-04 16:33:58 +020084
Derek Allard2067d1a2008-11-13 22:59:24 +000085// ------------------------------------------------------------------------
86
87/**
88 * Write File
89 *
90 * Writes data to the file specified in the path.
91 * Creates a new file if non-existent.
92 *
93 * @access public
94 * @param string path to file
95 * @param string file data
96 * @return bool
Barry Mienydd671972010-10-04 16:33:58 +020097 */
Derek Allard2067d1a2008-11-13 22:59:24 +000098if ( ! function_exists('write_file'))
99{
100 function write_file($path, $data, $mode = FOPEN_WRITE_CREATE_DESTRUCTIVE)
101 {
102 if ( ! $fp = @fopen($path, $mode))
103 {
104 return FALSE;
105 }
Barry Mienydd671972010-10-04 16:33:58 +0200106
Derek Allard2067d1a2008-11-13 22:59:24 +0000107 flock($fp, LOCK_EX);
108 fwrite($fp, $data);
109 flock($fp, LOCK_UN);
Barry Mienydd671972010-10-04 16:33:58 +0200110 fclose($fp);
Derek Allard2067d1a2008-11-13 22:59:24 +0000111
112 return TRUE;
113 }
114}
Barry Mienydd671972010-10-04 16:33:58 +0200115
Derek Allard2067d1a2008-11-13 22:59:24 +0000116// ------------------------------------------------------------------------
117
118/**
119 * Delete Files
120 *
121 * Deletes all files contained in the supplied directory path.
122 * Files must be writable or owned by the system in order to be deleted.
123 * If the second parameter is set to TRUE, any directories contained
124 * within the supplied base directory will be nuked as well.
125 *
126 * @access public
127 * @param string path to file
128 * @param bool whether to delete any directories found in the path
129 * @return bool
Barry Mienydd671972010-10-04 16:33:58 +0200130 */
Derek Allard2067d1a2008-11-13 22:59:24 +0000131if ( ! function_exists('delete_files'))
132{
133 function delete_files($path, $del_dir = FALSE, $level = 0)
Barry Mienydd671972010-10-04 16:33:58 +0200134 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000135 // Trim the trailing slash
Derek Jonesc37f0e12009-04-21 13:33:40 +0000136 $path = rtrim($path, DIRECTORY_SEPARATOR);
Barry Mienydd671972010-10-04 16:33:58 +0200137
Derek Allard2067d1a2008-11-13 22:59:24 +0000138 if ( ! $current_dir = @opendir($path))
Greg Aker3e9519e2010-01-15 00:09:34 +0000139 {
Barry Mienydd671972010-10-04 16:33:58 +0200140 return FALSE;
Greg Aker3e9519e2010-01-15 00:09:34 +0000141 }
Barry Mienydd671972010-10-04 16:33:58 +0200142
Pascal Kriete45e3cdf2011-02-14 13:26:20 -0500143 while (FALSE !== ($filename = @readdir($current_dir)))
Derek Allard2067d1a2008-11-13 22:59:24 +0000144 {
Andrey Andreev8bf6bb62012-01-06 16:11:04 +0200145 if ($filename !== '.' and $filename !== '..')
Derek Allard2067d1a2008-11-13 22:59:24 +0000146 {
Andrey Andreev8bf6bb62012-01-06 16:11:04 +0200147 if (is_dir($path.DIRECTORY_SEPARATOR.$filename) && $filename[0] !== '.')
Derek Allard2067d1a2008-11-13 22:59:24 +0000148 {
Andrey Andreev8bf6bb62012-01-06 16:11:04 +0200149 delete_files($path.DIRECTORY_SEPARATOR.$filename, $del_dir, $level + 1);
Derek Allard2067d1a2008-11-13 22:59:24 +0000150 }
151 else
152 {
Derek Jonesc37f0e12009-04-21 13:33:40 +0000153 unlink($path.DIRECTORY_SEPARATOR.$filename);
Derek Allard2067d1a2008-11-13 22:59:24 +0000154 }
155 }
156 }
157 @closedir($current_dir);
Barry Mienydd671972010-10-04 16:33:58 +0200158
Derek Allard2067d1a2008-11-13 22:59:24 +0000159 if ($del_dir == TRUE AND $level > 0)
160 {
Greg Aker3e9519e2010-01-15 00:09:34 +0000161 return @rmdir($path);
Derek Allard2067d1a2008-11-13 22:59:24 +0000162 }
Barry Mienydd671972010-10-04 16:33:58 +0200163
Greg Aker3e9519e2010-01-15 00:09:34 +0000164 return TRUE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000165 }
166}
167
168// ------------------------------------------------------------------------
169
170/**
171 * Get Filenames
172 *
Barry Mienydd671972010-10-04 16:33:58 +0200173 * Reads the specified directory and builds an array containing the filenames.
Derek Allard2067d1a2008-11-13 22:59:24 +0000174 * Any sub-folders contained within the specified path are read as well.
175 *
176 * @access public
177 * @param string path to source
178 * @param bool whether to include the path as part of the filename
179 * @param bool internal variable to determine recursion status - do not use in calls
180 * @return array
Barry Mienydd671972010-10-04 16:33:58 +0200181 */
Derek Allard2067d1a2008-11-13 22:59:24 +0000182if ( ! function_exists('get_filenames'))
183{
184 function get_filenames($source_dir, $include_path = FALSE, $_recursion = FALSE)
185 {
186 static $_filedata = array();
Barry Mienydd671972010-10-04 16:33:58 +0200187
Derek Allard2067d1a2008-11-13 22:59:24 +0000188 if ($fp = @opendir($source_dir))
189 {
190 // reset the array and make sure $source_dir has a trailing slash on the initial call
191 if ($_recursion === FALSE)
192 {
193 $_filedata = array();
194 $source_dir = rtrim(realpath($source_dir), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
195 }
Barry Mienydd671972010-10-04 16:33:58 +0200196
Derek Allard2067d1a2008-11-13 22:59:24 +0000197 while (FALSE !== ($file = readdir($fp)))
198 {
Andrey Andreev3b8ad8f2012-01-10 18:09:07 +0200199 if (@is_dir($source_dir.$file) && $file[0] !== '.')
Derek Allard2067d1a2008-11-13 22:59:24 +0000200 {
Barry Mienydd671972010-10-04 16:33:58 +0200201 get_filenames($source_dir.$file.DIRECTORY_SEPARATOR, $include_path, TRUE);
Derek Allard2067d1a2008-11-13 22:59:24 +0000202 }
Andrey Andreev3b8ad8f2012-01-10 18:09:07 +0200203 elseif ($file[0] !== '.')
Derek Allard2067d1a2008-11-13 22:59:24 +0000204 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000205 $_filedata[] = ($include_path == TRUE) ? $source_dir.$file : $file;
206 }
207 }
Andrey Andreev3b8ad8f2012-01-10 18:09:07 +0200208 closedir($fp);
Andrey Andreev8bf6bb62012-01-06 16:11:04 +0200209
Derek Allard2067d1a2008-11-13 22:59:24 +0000210 return $_filedata;
211 }
Andrey Andreev8bf6bb62012-01-06 16:11:04 +0200212
213 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000214 }
215}
216
217// --------------------------------------------------------------------
218
219/**
220 * Get Directory File Information
221 *
Barry Mienydd671972010-10-04 16:33:58 +0200222 * Reads the specified directory and builds an array containing the filenames,
Derek Allard2067d1a2008-11-13 22:59:24 +0000223 * filesize, dates, and permissions
224 *
225 * Any sub-folders contained within the specified path are read as well.
226 *
227 * @access public
228 * @param string path to source
Derek Jones626d39f2010-03-02 23:14:56 -0600229 * @param bool Look only at the top level directory specified?
Derek Allard2067d1a2008-11-13 22:59:24 +0000230 * @param bool internal variable to determine recursion status - do not use in calls
231 * @return array
Barry Mienydd671972010-10-04 16:33:58 +0200232 */
Derek Allard2067d1a2008-11-13 22:59:24 +0000233if ( ! function_exists('get_dir_file_info'))
234{
Derek Jones788b00f2009-11-27 18:00:20 +0000235 function get_dir_file_info($source_dir, $top_level_only = TRUE, $_recursion = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000236 {
Derek Jones63dc27f2009-02-10 21:59:20 +0000237 static $_filedata = array();
Derek Allard2067d1a2008-11-13 22:59:24 +0000238 $relative_path = $source_dir;
Derek Jonesc37f0e12009-04-21 13:33:40 +0000239
Derek Allard2067d1a2008-11-13 22:59:24 +0000240 if ($fp = @opendir($source_dir))
241 {
242 // reset the array and make sure $source_dir has a trailing slash on the initial call
243 if ($_recursion === FALSE)
244 {
245 $_filedata = array();
246 $source_dir = rtrim(realpath($source_dir), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
247 }
248
Derek Jones788b00f2009-11-27 18:00:20 +0000249 // foreach (scandir($source_dir, 1) as $file) // In addition to being PHP5+, scandir() is simply not as fast
Derek Allard2067d1a2008-11-13 22:59:24 +0000250 while (FALSE !== ($file = readdir($fp)))
251 {
Andrey Andreev3b8ad8f2012-01-10 18:09:07 +0200252 if (@is_dir($source_dir.$file) && $file[0] !== '.' && $top_level_only === FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000253 {
Barry Mienydd671972010-10-04 16:33:58 +0200254 get_dir_file_info($source_dir.$file.DIRECTORY_SEPARATOR, $top_level_only, TRUE);
255 }
Andrey Andreev3b8ad8f2012-01-10 18:09:07 +0200256 elseif ($file[0] !== '.')
Barry Mienydd671972010-10-04 16:33:58 +0200257 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000258 $_filedata[$file] = get_file_info($source_dir.$file);
259 $_filedata[$file]['relative_path'] = $relative_path;
260 }
261 }
Andrey Andreev3b8ad8f2012-01-10 18:09:07 +0200262 closedir($fp);
Derek Jones788b00f2009-11-27 18:00:20 +0000263
Derek Allard2067d1a2008-11-13 22:59:24 +0000264 return $_filedata;
265 }
Andrey Andreev8bf6bb62012-01-06 16:11:04 +0200266
267 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000268 }
269}
270
271// --------------------------------------------------------------------
272
273/**
274* Get File Info
275*
276* Given a file and path, returns the name, path, size, date modified
277* Second parameter allows you to explicitly declare what information you want returned
278* Options are: name, server_path, size, date, readable, writable, executable, fileperms
279* Returns FALSE if the file cannot be found.
280*
281* @access public
Derek Jonesc37f0e12009-04-21 13:33:40 +0000282* @param string path to file
283* @param mixed array or comma separated string of information returned
Derek Allard2067d1a2008-11-13 22:59:24 +0000284* @return array
285*/
286if ( ! function_exists('get_file_info'))
287{
288 function get_file_info($file, $returned_values = array('name', 'server_path', 'size', 'date'))
289 {
290
291 if ( ! file_exists($file))
292 {
293 return FALSE;
294 }
295
296 if (is_string($returned_values))
297 {
298 $returned_values = explode(',', $returned_values);
299 }
300
301 foreach ($returned_values as $key)
302 {
303 switch ($key)
304 {
305 case 'name':
Derek Jonesc37f0e12009-04-21 13:33:40 +0000306 $fileinfo['name'] = substr(strrchr($file, DIRECTORY_SEPARATOR), 1);
Derek Allard2067d1a2008-11-13 22:59:24 +0000307 break;
308 case 'server_path':
309 $fileinfo['server_path'] = $file;
310 break;
311 case 'size':
312 $fileinfo['size'] = filesize($file);
313 break;
314 case 'date':
Robin Sowell73c19fc2010-04-09 11:18:26 -0400315 $fileinfo['date'] = filemtime($file);
Derek Allard2067d1a2008-11-13 22:59:24 +0000316 break;
317 case 'readable':
318 $fileinfo['readable'] = is_readable($file);
319 break;
320 case 'writable':
Derek Jones37f4b9c2011-07-01 17:56:50 -0500321 // There are known problems using is_weritable on IIS. It may not be reliable - consider fileperms()
Derek Allard2067d1a2008-11-13 22:59:24 +0000322 $fileinfo['writable'] = is_writable($file);
323 break;
324 case 'executable':
325 $fileinfo['executable'] = is_executable($file);
326 break;
327 case 'fileperms':
328 $fileinfo['fileperms'] = fileperms($file);
329 break;
330 }
331 }
332
333 return $fileinfo;
334 }
335}
336
337// --------------------------------------------------------------------
338
339/**
340 * Get Mime by Extension
341 *
Barry Mienydd671972010-10-04 16:33:58 +0200342 * Translates a file extension into a mime type based on config/mimes.php.
Derek Allard2067d1a2008-11-13 22:59:24 +0000343 * Returns FALSE if it can't determine the type, or open the mime config file
344 *
345 * Note: this is NOT an accurate way of determining file mime types, and is here strictly as a convenience
346 * It should NOT be trusted, and should certainly NOT be used for security
347 *
348 * @access public
349 * @param string path to file
350 * @return mixed
Barry Mienydd671972010-10-04 16:33:58 +0200351 */
Derek Allard2067d1a2008-11-13 22:59:24 +0000352if ( ! function_exists('get_mime_by_extension'))
353{
354 function get_mime_by_extension($file)
355 {
Derek Allard95023112010-01-17 07:51:21 +0000356 $extension = strtolower(substr(strrchr($file, '.'), 1));
Derek Jonesc37f0e12009-04-21 13:33:40 +0000357
Derek Allard2067d1a2008-11-13 22:59:24 +0000358 global $mimes;
Derek Jonesc37f0e12009-04-21 13:33:40 +0000359
Derek Allard2067d1a2008-11-13 22:59:24 +0000360 if ( ! is_array($mimes))
361 {
Andrey Andreev3b8ad8f2012-01-10 18:09:07 +0200362 if (defined('ENVIRONMENT') && is_file(APPPATH.'config/'.ENVIRONMENT.'/mimes.php'))
Greg Akerd96f8822011-12-27 16:23:47 -0600363 {
364 include(APPPATH.'config/'.ENVIRONMENT.'/mimes.php');
365 }
366 elseif (is_file(APPPATH.'config/mimes.php'))
367 {
368 include(APPPATH.'config/mimes.php');
369 }
Eric Barnes92808342011-03-18 09:02:37 -0400370
bubbafoley0ea04142011-03-17 14:55:41 -0500371 if ( ! is_array($mimes))
Derek Allard2067d1a2008-11-13 22:59:24 +0000372 {
373 return FALSE;
374 }
375 }
376
377 if (array_key_exists($extension, $mimes))
378 {
379 if (is_array($mimes[$extension]))
380 {
381 // Multiple mime types, just give the first one
382 return current($mimes[$extension]);
383 }
384 else
385 {
386 return $mimes[$extension];
387 }
388 }
Andrey Andreev8bf6bb62012-01-06 16:11:04 +0200389
390 return FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000391 }
392}
393
394// --------------------------------------------------------------------
395
396/**
397 * Symbolic Permissions
398 *
399 * Takes a numeric value representing a file's permissions and returns
400 * standard symbolic notation representing that value
401 *
402 * @access public
403 * @param int
404 * @return string
Barry Mienydd671972010-10-04 16:33:58 +0200405 */
Derek Allard2067d1a2008-11-13 22:59:24 +0000406if ( ! function_exists('symbolic_permissions'))
407{
408 function symbolic_permissions($perms)
Barry Mienydd671972010-10-04 16:33:58 +0200409 {
Andrey Andreev8bf6bb62012-01-06 16:11:04 +0200410 if (($perms & 0xC000) === 0xC000)
Derek Allard2067d1a2008-11-13 22:59:24 +0000411 {
412 $symbolic = 's'; // Socket
413 }
Andrey Andreev8bf6bb62012-01-06 16:11:04 +0200414 elseif (($perms & 0xA000) === 0xA000)
Derek Allard2067d1a2008-11-13 22:59:24 +0000415 {
416 $symbolic = 'l'; // Symbolic Link
417 }
Andrey Andreev8bf6bb62012-01-06 16:11:04 +0200418 elseif (($perms & 0x8000) === 0x8000)
Derek Allard2067d1a2008-11-13 22:59:24 +0000419 {
420 $symbolic = '-'; // Regular
421 }
Andrey Andreev8bf6bb62012-01-06 16:11:04 +0200422 elseif (($perms & 0x6000) === 0x6000)
Derek Allard2067d1a2008-11-13 22:59:24 +0000423 {
424 $symbolic = 'b'; // Block special
425 }
Andrey Andreev8bf6bb62012-01-06 16:11:04 +0200426 elseif (($perms & 0x4000) === 0x4000)
Derek Allard2067d1a2008-11-13 22:59:24 +0000427 {
428 $symbolic = 'd'; // Directory
429 }
Andrey Andreev8bf6bb62012-01-06 16:11:04 +0200430 elseif (($perms & 0x2000) === 0x2000)
Derek Allard2067d1a2008-11-13 22:59:24 +0000431 {
432 $symbolic = 'c'; // Character special
433 }
Andrey Andreev8bf6bb62012-01-06 16:11:04 +0200434 elseif (($perms & 0x1000) === 0x1000)
Derek Allard2067d1a2008-11-13 22:59:24 +0000435 {
436 $symbolic = 'p'; // FIFO pipe
437 }
438 else
439 {
440 $symbolic = 'u'; // Unknown
441 }
442
443 // Owner
Andrey Andreev8bf6bb62012-01-06 16:11:04 +0200444 $symbolic .= (($perms & 0x0100) ? 'r' : '-')
445 . (($perms & 0x0080) ? 'w' : '-')
446 . (($perms & 0x0040) ? (($perms & 0x0800) ? 's' : 'x' ) : (($perms & 0x0800) ? 'S' : '-'));
Derek Allard2067d1a2008-11-13 22:59:24 +0000447
448 // Group
Andrey Andreev8bf6bb62012-01-06 16:11:04 +0200449 $symbolic .= (($perms & 0x0020) ? 'r' : '-')
450 . (($perms & 0x0010) ? 'w' : '-')
451 . (($perms & 0x0008) ? (($perms & 0x0400) ? 's' : 'x' ) : (($perms & 0x0400) ? 'S' : '-'));
Derek Allard2067d1a2008-11-13 22:59:24 +0000452
453 // World
Andrey Andreev8bf6bb62012-01-06 16:11:04 +0200454 $symbolic .= (($perms & 0x0004) ? 'r' : '-')
455 . (($perms & 0x0002) ? 'w' : '-')
456 . (($perms & 0x0001) ? (($perms & 0x0200) ? 't' : 'x' ) : (($perms & 0x0200) ? 'T' : '-'));
Derek Allard2067d1a2008-11-13 22:59:24 +0000457
Barry Mienydd671972010-10-04 16:33:58 +0200458 return $symbolic;
Derek Allard2067d1a2008-11-13 22:59:24 +0000459 }
460}
461
462// --------------------------------------------------------------------
463
464/**
465 * Octal Permissions
466 *
467 * Takes a numeric value representing a file's permissions and returns
468 * a three character string representing the file's octal permissions
469 *
470 * @access public
471 * @param int
472 * @return string
Barry Mienydd671972010-10-04 16:33:58 +0200473 */
Derek Allard2067d1a2008-11-13 22:59:24 +0000474if ( ! function_exists('octal_permissions'))
475{
476 function octal_permissions($perms)
477 {
478 return substr(sprintf('%o', $perms), -3);
479 }
480}
481
Derek Allard2067d1a2008-11-13 22:59:24 +0000482/* End of file file_helper.php */
Andrey Andreev8bf6bb62012-01-06 16:11:04 +0200483/* Location: ./system/helpers/file_helper.php */