PageRenderTime 57ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 1ms

/system/libraries/Upload.php

https://bitbucket.org/siriusdely/codeigniter-reactor
PHP | 1013 lines | 610 code | 131 blank | 272 comment | 83 complexity | fa227eec6a7369ce8c383188ac5c7768 MD5 | raw file
  1. <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
  2. /**
  3. * CodeIgniter
  4. *
  5. * An open source application development framework for PHP 5.1.6 or newer
  6. *
  7. * @package CodeIgniter
  8. * @author ExpressionEngine Dev Team
  9. * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc.
  10. * @license http://codeigniter.com/user_guide/license.html
  11. * @link http://codeigniter.com
  12. * @since Version 1.0
  13. * @filesource
  14. */
  15. // ------------------------------------------------------------------------
  16. /**
  17. * File Uploading Class
  18. *
  19. * @package CodeIgniter
  20. * @subpackage Libraries
  21. * @category Uploads
  22. * @author ExpressionEngine Dev Team
  23. * @link http://codeigniter.com/user_guide/libraries/file_uploading.html
  24. */
  25. class CI_Upload {
  26. public $max_size = 0;
  27. public $max_width = 0;
  28. public $max_height = 0;
  29. public $max_filename = 0;
  30. public $allowed_types = "";
  31. public $file_temp = "";
  32. public $file_name = "";
  33. public $orig_name = "";
  34. public $file_type = "";
  35. public $file_size = "";
  36. public $file_ext = "";
  37. public $upload_path = "";
  38. public $overwrite = FALSE;
  39. public $encrypt_name = FALSE;
  40. public $is_image = FALSE;
  41. public $image_width = '';
  42. public $image_height = '';
  43. public $image_type = '';
  44. public $image_size_str = '';
  45. public $error_msg = array();
  46. public $mimes = array();
  47. public $remove_spaces = TRUE;
  48. public $xss_clean = FALSE;
  49. public $temp_prefix = "temp_file_";
  50. public $client_name = '';
  51. protected $_file_name_override = '';
  52. /**
  53. * Constructor
  54. *
  55. * @access public
  56. */
  57. public function __construct($props = array())
  58. {
  59. if (count($props) > 0)
  60. {
  61. $this->initialize($props);
  62. }
  63. log_message('debug', "Upload Class Initialized");
  64. }
  65. // --------------------------------------------------------------------
  66. /**
  67. * Initialize preferences
  68. *
  69. * @param array
  70. * @return void
  71. */
  72. public function initialize($config = array())
  73. {
  74. $defaults = array(
  75. 'max_size' => 0,
  76. 'max_width' => 0,
  77. 'max_height' => 0,
  78. 'max_filename' => 0,
  79. 'allowed_types' => "",
  80. 'file_temp' => "",
  81. 'file_name' => "",
  82. 'orig_name' => "",
  83. 'file_type' => "",
  84. 'file_size' => "",
  85. 'file_ext' => "",
  86. 'upload_path' => "",
  87. 'overwrite' => FALSE,
  88. 'encrypt_name' => FALSE,
  89. 'is_image' => FALSE,
  90. 'image_width' => '',
  91. 'image_height' => '',
  92. 'image_type' => '',
  93. 'image_size_str' => '',
  94. 'error_msg' => array(),
  95. 'mimes' => array(),
  96. 'remove_spaces' => TRUE,
  97. 'xss_clean' => FALSE,
  98. 'temp_prefix' => "temp_file_",
  99. 'client_name' => ''
  100. );
  101. foreach ($defaults as $key => $val)
  102. {
  103. if (isset($config[$key]))
  104. {
  105. $method = 'set_'.$key;
  106. if (method_exists($this, $method))
  107. {
  108. $this->$method($config[$key]);
  109. }
  110. else
  111. {
  112. $this->$key = $config[$key];
  113. }
  114. }
  115. else
  116. {
  117. $this->$key = $val;
  118. }
  119. }
  120. // if a file_name was provided in the config, use it instead of the user input
  121. // supplied file name for all uploads until initialized again
  122. $this->_file_name_override = $this->file_name;
  123. }
  124. // --------------------------------------------------------------------
  125. /**
  126. * Perform the file upload
  127. *
  128. * @return bool
  129. */
  130. public function do_upload($field = 'userfile')
  131. {
  132. // Is $_FILES[$field] set? If not, no reason to continue.
  133. if ( ! isset($_FILES[$field]))
  134. {
  135. $this->set_error('upload_no_file_selected');
  136. return FALSE;
  137. }
  138. // Is the upload path valid?
  139. if ( ! $this->validate_upload_path())
  140. {
  141. // errors will already be set by validate_upload_path() so just return FALSE
  142. return FALSE;
  143. }
  144. // Was the file able to be uploaded? If not, determine the reason why.
  145. if ( ! is_uploaded_file($_FILES[$field]['tmp_name']))
  146. {
  147. $error = ( ! isset($_FILES[$field]['error'])) ? 4 : $_FILES[$field]['error'];
  148. switch($error)
  149. {
  150. case 1: // UPLOAD_ERR_INI_SIZE
  151. $this->set_error('upload_file_exceeds_limit');
  152. break;
  153. case 2: // UPLOAD_ERR_FORM_SIZE
  154. $this->set_error('upload_file_exceeds_form_limit');
  155. break;
  156. case 3: // UPLOAD_ERR_PARTIAL
  157. $this->set_error('upload_file_partial');
  158. break;
  159. case 4: // UPLOAD_ERR_NO_FILE
  160. $this->set_error('upload_no_file_selected');
  161. break;
  162. case 6: // UPLOAD_ERR_NO_TMP_DIR
  163. $this->set_error('upload_no_temp_directory');
  164. break;
  165. case 7: // UPLOAD_ERR_CANT_WRITE
  166. $this->set_error('upload_unable_to_write_file');
  167. break;
  168. case 8: // UPLOAD_ERR_EXTENSION
  169. $this->set_error('upload_stopped_by_extension');
  170. break;
  171. default : $this->set_error('upload_no_file_selected');
  172. break;
  173. }
  174. return FALSE;
  175. }
  176. // Set the uploaded data as class variables
  177. $this->file_temp = $_FILES[$field]['tmp_name'];
  178. $this->file_size = $_FILES[$field]['size'];
  179. $this->file_type = preg_replace("/^(.+?);.*$/", "\\1", $_FILES[$field]['type']);
  180. $this->file_type = strtolower(trim(stripslashes($this->file_type), '"'));
  181. $this->file_name = $this->_prep_filename($_FILES[$field]['name']);
  182. $this->file_ext = $this->get_extension($this->file_name);
  183. $this->client_name = $this->file_name;
  184. // Is the file type allowed to be uploaded?
  185. if ( ! $this->is_allowed_filetype())
  186. {
  187. $this->set_error('upload_invalid_filetype');
  188. return FALSE;
  189. }
  190. // if we're overriding, let's now make sure the new name and type is allowed
  191. if ($this->_file_name_override != '')
  192. {
  193. $this->file_name = $this->_prep_filename($this->_file_name_override);
  194. // If no extension was provided in the file_name config item, use the uploaded one
  195. if (strpos($this->_file_name_override, '.') === FALSE)
  196. {
  197. $this->file_name .= $this->file_ext;
  198. }
  199. // An extension was provided, lets have it!
  200. else
  201. {
  202. $this->file_ext = $this->get_extension($this->_file_name_override);
  203. }
  204. if ( ! $this->is_allowed_filetype(TRUE))
  205. {
  206. $this->set_error('upload_invalid_filetype');
  207. return FALSE;
  208. }
  209. }
  210. // Convert the file size to kilobytes
  211. if ($this->file_size > 0)
  212. {
  213. $this->file_size = round($this->file_size/1024, 2);
  214. }
  215. // Is the file size within the allowed maximum?
  216. if ( ! $this->is_allowed_filesize())
  217. {
  218. $this->set_error('upload_invalid_filesize');
  219. return FALSE;
  220. }
  221. // Are the image dimensions within the allowed size?
  222. // Note: This can fail if the server has an open_basdir restriction.
  223. if ( ! $this->is_allowed_dimensions())
  224. {
  225. $this->set_error('upload_invalid_dimensions');
  226. return FALSE;
  227. }
  228. // Sanitize the file name for security
  229. $this->file_name = $this->clean_file_name($this->file_name);
  230. // Truncate the file name if it's too long
  231. if ($this->max_filename > 0)
  232. {
  233. $this->file_name = $this->limit_filename_length($this->file_name, $this->max_filename);
  234. }
  235. // Remove white spaces in the name
  236. if ($this->remove_spaces == TRUE)
  237. {
  238. $this->file_name = preg_replace("/\s+/", "_", $this->file_name);
  239. }
  240. /*
  241. * Validate the file name
  242. * This function appends an number onto the end of
  243. * the file if one with the same name already exists.
  244. * If it returns false there was a problem.
  245. */
  246. $this->orig_name = $this->file_name;
  247. if ($this->overwrite == FALSE)
  248. {
  249. $this->file_name = $this->set_filename($this->upload_path, $this->file_name);
  250. if ($this->file_name === FALSE)
  251. {
  252. return FALSE;
  253. }
  254. }
  255. /*
  256. * Run the file through the XSS hacking filter
  257. * This helps prevent malicious code from being
  258. * embedded within a file. Scripts can easily
  259. * be disguised as images or other file types.
  260. */
  261. if ($this->xss_clean)
  262. {
  263. if ($this->do_xss_clean() === FALSE)
  264. {
  265. $this->set_error('upload_unable_to_write_file');
  266. return FALSE;
  267. }
  268. }
  269. /*
  270. * Move the file to the final destination
  271. * To deal with different server configurations
  272. * we'll attempt to use copy() first. If that fails
  273. * we'll use move_uploaded_file(). One of the two should
  274. * reliably work in most environments
  275. */
  276. if ( ! @copy($this->file_temp, $this->upload_path.$this->file_name))
  277. {
  278. if ( ! @move_uploaded_file($this->file_temp, $this->upload_path.$this->file_name))
  279. {
  280. $this->set_error('upload_destination_error');
  281. return FALSE;
  282. }
  283. }
  284. /*
  285. * Set the finalized image dimensions
  286. * This sets the image width/height (assuming the
  287. * file was an image). We use this information
  288. * in the "data" function.
  289. */
  290. $this->set_image_properties($this->upload_path.$this->file_name);
  291. return TRUE;
  292. }
  293. // --------------------------------------------------------------------
  294. /**
  295. * Finalized Data Array
  296. *
  297. * Returns an associative array containing all of the information
  298. * related to the upload, allowing the developer easy access in one array.
  299. *
  300. * @return array
  301. */
  302. public function data()
  303. {
  304. return array (
  305. 'file_name' => $this->file_name,
  306. 'file_type' => $this->file_type,
  307. 'file_path' => $this->upload_path,
  308. 'full_path' => $this->upload_path.$this->file_name,
  309. 'raw_name' => str_replace($this->file_ext, '', $this->file_name),
  310. 'orig_name' => $this->orig_name,
  311. 'client_name' => $this->client_name,
  312. 'file_ext' => $this->file_ext,
  313. 'file_size' => $this->file_size,
  314. 'is_image' => $this->is_image(),
  315. 'image_width' => $this->image_width,
  316. 'image_height' => $this->image_height,
  317. 'image_type' => $this->image_type,
  318. 'image_size_str' => $this->image_size_str,
  319. );
  320. }
  321. // --------------------------------------------------------------------
  322. /**
  323. * Set Upload Path
  324. *
  325. * @param string
  326. * @return void
  327. */
  328. public function set_upload_path($path)
  329. {
  330. // Make sure it has a trailing slash
  331. $this->upload_path = rtrim($path, '/').'/';
  332. }
  333. // --------------------------------------------------------------------
  334. /**
  335. * Set the file name
  336. *
  337. * This function takes a filename/path as input and looks for the
  338. * existence of a file with the same name. If found, it will append a
  339. * number to the end of the filename to avoid overwriting a pre-existing file.
  340. *
  341. * @param string
  342. * @param string
  343. * @return string
  344. */
  345. public function set_filename($path, $filename)
  346. {
  347. if ($this->encrypt_name == TRUE)
  348. {
  349. mt_srand();
  350. $filename = md5(uniqid(mt_rand())).$this->file_ext;
  351. }
  352. if ( ! file_exists($path.$filename))
  353. {
  354. return $filename;
  355. }
  356. $filename = str_replace($this->file_ext, '', $filename);
  357. $new_filename = '';
  358. for ($i = 1; $i < 100; $i++)
  359. {
  360. if ( ! file_exists($path.$filename.$i.$this->file_ext))
  361. {
  362. $new_filename = $filename.$i.$this->file_ext;
  363. break;
  364. }
  365. }
  366. if ($new_filename == '')
  367. {
  368. $this->set_error('upload_bad_filename');
  369. return FALSE;
  370. }
  371. else
  372. {
  373. return $new_filename;
  374. }
  375. }
  376. // --------------------------------------------------------------------
  377. /**
  378. * Set Maximum File Size
  379. *
  380. * @param integer
  381. * @return void
  382. */
  383. public function set_max_filesize($n)
  384. {
  385. $this->max_size = ((int) $n < 0) ? 0: (int) $n;
  386. }
  387. // --------------------------------------------------------------------
  388. /**
  389. * Set Maximum File Name Length
  390. *
  391. * @param integer
  392. * @return void
  393. */
  394. public function set_max_filename($n)
  395. {
  396. $this->max_filename = ((int) $n < 0) ? 0: (int) $n;
  397. }
  398. // --------------------------------------------------------------------
  399. /**
  400. * Set Maximum Image Width
  401. *
  402. * @param integer
  403. * @return void
  404. */
  405. public function set_max_width($n)
  406. {
  407. $this->max_width = ((int) $n < 0) ? 0: (int) $n;
  408. }
  409. // --------------------------------------------------------------------
  410. /**
  411. * Set Maximum Image Height
  412. *
  413. * @param integer
  414. * @return void
  415. */
  416. public function set_max_height($n)
  417. {
  418. $this->max_height = ((int) $n < 0) ? 0: (int) $n;
  419. }
  420. // --------------------------------------------------------------------
  421. /**
  422. * Set Allowed File Types
  423. *
  424. * @param string
  425. * @return void
  426. */
  427. public function set_allowed_types($types)
  428. {
  429. if ( ! is_array($types) && $types == '*')
  430. {
  431. $this->allowed_types = '*';
  432. return;
  433. }
  434. $this->allowed_types = explode('|', $types);
  435. }
  436. // --------------------------------------------------------------------
  437. /**
  438. * Set Image Properties
  439. *
  440. * Uses GD to determine the width/height/type of image
  441. *
  442. * @param string
  443. * @return void
  444. */
  445. public function set_image_properties($path = '')
  446. {
  447. if ( ! $this->is_image())
  448. {
  449. return;
  450. }
  451. if (function_exists('getimagesize'))
  452. {
  453. if (FALSE !== ($D = @getimagesize($path)))
  454. {
  455. $types = array(1 => 'gif', 2 => 'jpeg', 3 => 'png');
  456. $this->image_width = $D['0'];
  457. $this->image_height = $D['1'];
  458. $this->image_type = ( ! isset($types[$D['2']])) ? 'unknown' : $types[$D['2']];
  459. $this->image_size_str = $D['3']; // string containing height and width
  460. }
  461. }
  462. }
  463. // --------------------------------------------------------------------
  464. /**
  465. * Set XSS Clean
  466. *
  467. * Enables the XSS flag so that the file that was uploaded
  468. * will be run through the XSS filter.
  469. *
  470. * @param bool
  471. * @return void
  472. */
  473. public function set_xss_clean($flag = FALSE)
  474. {
  475. $this->xss_clean = ($flag == TRUE) ? TRUE : FALSE;
  476. }
  477. // --------------------------------------------------------------------
  478. /**
  479. * Validate the image
  480. *
  481. * @return bool
  482. */
  483. public function is_image()
  484. {
  485. // IE will sometimes return odd mime-types during upload, so here we just standardize all
  486. // jpegs or pngs to the same file type.
  487. $png_mimes = array('image/x-png');
  488. $jpeg_mimes = array('image/jpg', 'image/jpe', 'image/jpeg', 'image/pjpeg');
  489. if (in_array($this->file_type, $png_mimes))
  490. {
  491. $this->file_type = 'image/png';
  492. }
  493. if (in_array($this->file_type, $jpeg_mimes))
  494. {
  495. $this->file_type = 'image/jpeg';
  496. }
  497. $img_mimes = array(
  498. 'image/gif',
  499. 'image/jpeg',
  500. 'image/png',
  501. );
  502. return (in_array($this->file_type, $img_mimes, TRUE)) ? TRUE : FALSE;
  503. }
  504. // --------------------------------------------------------------------
  505. /**
  506. * Verify that the filetype is allowed
  507. *
  508. * @return bool
  509. */
  510. public function is_allowed_filetype($ignore_mime = FALSE)
  511. {
  512. if ($this->allowed_types == '*')
  513. {
  514. return TRUE;
  515. }
  516. if (count($this->allowed_types) == 0 OR ! is_array($this->allowed_types))
  517. {
  518. $this->set_error('upload_no_file_types');
  519. return FALSE;
  520. }
  521. $ext = strtolower(ltrim($this->file_ext, '.'));
  522. if ( ! in_array($ext, $this->allowed_types))
  523. {
  524. return FALSE;
  525. }
  526. // Images get some additional checks
  527. $image_types = array('gif', 'jpg', 'jpeg', 'png', 'jpe');
  528. if (in_array($ext, $image_types))
  529. {
  530. if (getimagesize($this->file_temp) === FALSE)
  531. {
  532. return FALSE;
  533. }
  534. }
  535. if ($ignore_mime === TRUE)
  536. {
  537. return TRUE;
  538. }
  539. $mime = $this->mimes_types($ext);
  540. if (is_array($mime))
  541. {
  542. if (in_array($this->file_type, $mime, TRUE))
  543. {
  544. return TRUE;
  545. }
  546. }
  547. elseif ($mime == $this->file_type)
  548. {
  549. return TRUE;
  550. }
  551. return FALSE;
  552. }
  553. // --------------------------------------------------------------------
  554. /**
  555. * Verify that the file is within the allowed size
  556. *
  557. * @return bool
  558. */
  559. public function is_allowed_filesize()
  560. {
  561. if ($this->max_size != 0 AND $this->file_size > $this->max_size)
  562. {
  563. return FALSE;
  564. }
  565. else
  566. {
  567. return TRUE;
  568. }
  569. }
  570. // --------------------------------------------------------------------
  571. /**
  572. * Verify that the image is within the allowed width/height
  573. *
  574. * @return bool
  575. */
  576. public function is_allowed_dimensions()
  577. {
  578. if ( ! $this->is_image())
  579. {
  580. return TRUE;
  581. }
  582. if (function_exists('getimagesize'))
  583. {
  584. $D = @getimagesize($this->file_temp);
  585. if ($this->max_width > 0 AND $D['0'] > $this->max_width)
  586. {
  587. return FALSE;
  588. }
  589. if ($this->max_height > 0 AND $D['1'] > $this->max_height)
  590. {
  591. return FALSE;
  592. }
  593. return TRUE;
  594. }
  595. return TRUE;
  596. }
  597. // --------------------------------------------------------------------
  598. /**
  599. * Validate Upload Path
  600. *
  601. * Verifies that it is a valid upload path with proper permissions.
  602. *
  603. *
  604. * @return bool
  605. */
  606. public function validate_upload_path()
  607. {
  608. if ($this->upload_path == '')
  609. {
  610. $this->set_error('upload_no_filepath');
  611. return FALSE;
  612. }
  613. if (function_exists('realpath') AND @realpath($this->upload_path) !== FALSE)
  614. {
  615. $this->upload_path = str_replace("\\", "/", realpath($this->upload_path));
  616. }
  617. if ( ! @is_dir($this->upload_path))
  618. {
  619. $this->set_error('upload_no_filepath');
  620. return FALSE;
  621. }
  622. if ( ! is_really_writable($this->upload_path))
  623. {
  624. $this->set_error('upload_not_writable');
  625. return FALSE;
  626. }
  627. $this->upload_path = preg_replace("/(.+?)\/*$/", "\\1/", $this->upload_path);
  628. return TRUE;
  629. }
  630. // --------------------------------------------------------------------
  631. /**
  632. * Extract the file extension
  633. *
  634. * @param string
  635. * @return string
  636. */
  637. public function get_extension($filename)
  638. {
  639. $x = explode('.', $filename);
  640. return '.'.end($x);
  641. }
  642. // --------------------------------------------------------------------
  643. /**
  644. * Clean the file name for security
  645. *
  646. * @param string
  647. * @return string
  648. */
  649. public function clean_file_name($filename)
  650. {
  651. $bad = array(
  652. "<!--",
  653. "-->",
  654. "'",
  655. "<",
  656. ">",
  657. '"',
  658. '&',
  659. '$',
  660. '=',
  661. ';',
  662. '?',
  663. '/',
  664. "%20",
  665. "%22",
  666. "%3c", // <
  667. "%253c", // <
  668. "%3e", // >
  669. "%0e", // >
  670. "%28", // (
  671. "%29", // )
  672. "%2528", // (
  673. "%26", // &
  674. "%24", // $
  675. "%3f", // ?
  676. "%3b", // ;
  677. "%3d" // =
  678. );
  679. $filename = str_replace($bad, '', $filename);
  680. return stripslashes($filename);
  681. }
  682. // --------------------------------------------------------------------
  683. /**
  684. * Limit the File Name Length
  685. *
  686. * @param string
  687. * @return string
  688. */
  689. public function limit_filename_length($filename, $length)
  690. {
  691. if (strlen($filename) < $length)
  692. {
  693. return $filename;
  694. }
  695. $ext = '';
  696. if (strpos($filename, '.') !== FALSE)
  697. {
  698. $parts = explode('.', $filename);
  699. $ext = '.'.array_pop($parts);
  700. $filename = implode('.', $parts);
  701. }
  702. return substr($filename, 0, ($length - strlen($ext))).$ext;
  703. }
  704. // --------------------------------------------------------------------
  705. /**
  706. * Runs the file through the XSS clean function
  707. *
  708. * This prevents people from embedding malicious code in their files.
  709. * I'm not sure that it won't negatively affect certain files in unexpected ways,
  710. * but so far I haven't found that it causes trouble.
  711. *
  712. * @return void
  713. */
  714. public function do_xss_clean()
  715. {
  716. $file = $this->file_temp;
  717. if (filesize($file) == 0)
  718. {
  719. return FALSE;
  720. }
  721. if (function_exists('memory_get_usage') && memory_get_usage() && ini_get('memory_limit') != '')
  722. {
  723. $current = ini_get('memory_limit') * 1024 * 1024;
  724. // There was a bug/behavioural change in PHP 5.2, where numbers over one million get output
  725. // into scientific notation. number_format() ensures this number is an integer
  726. // http://bugs.php.net/bug.php?id=43053
  727. $new_memory = number_format(ceil(filesize($file) + $current), 0, '.', '');
  728. ini_set('memory_limit', $new_memory); // When an integer is used, the value is measured in bytes. - PHP.net
  729. }
  730. // If the file being uploaded is an image, then we should have no problem with XSS attacks (in theory), but
  731. // IE can be fooled into mime-type detecting a malformed image as an html file, thus executing an XSS attack on anyone
  732. // using IE who looks at the image. It does this by inspecting the first 255 bytes of an image. To get around this
  733. // CI will itself look at the first 255 bytes of an image to determine its relative safety. This can save a lot of
  734. // processor power and time if it is actually a clean image, as it will be in nearly all instances _except_ an
  735. // attempted XSS attack.
  736. if (function_exists('getimagesize') && @getimagesize($file) !== FALSE)
  737. {
  738. if (($file = @fopen($file, 'rb')) === FALSE) // "b" to force binary
  739. {
  740. return FALSE; // Couldn't open the file, return FALSE
  741. }
  742. $opening_bytes = fread($file, 256);
  743. fclose($file);
  744. // These are known to throw IE into mime-type detection chaos
  745. // <a, <body, <head, <html, <img, <plaintext, <pre, <script, <table, <title
  746. // title is basically just in SVG, but we filter it anyhow
  747. if ( ! preg_match('/<(a|body|head|html|img|plaintext|pre|script|table|title)[\s>]/i', $opening_bytes))
  748. {
  749. return TRUE; // its an image, no "triggers" detected in the first 256 bytes, we're good
  750. }
  751. }
  752. if (($data = @file_get_contents($file)) === FALSE)
  753. {
  754. return FALSE;
  755. }
  756. $CI =& get_instance();
  757. return $CI->security->xss_clean($data, TRUE);
  758. }
  759. // --------------------------------------------------------------------
  760. /**
  761. * Set an error message
  762. *
  763. * @param string
  764. * @return void
  765. */
  766. public function set_error($msg)
  767. {
  768. $CI =& get_instance();
  769. $CI->lang->load('upload');
  770. if (is_array($msg))
  771. {
  772. foreach ($msg as $val)
  773. {
  774. $msg = ($CI->lang->line($val) == FALSE) ? $val : $CI->lang->line($val);
  775. $this->error_msg[] = $msg;
  776. log_message('error', $msg);
  777. }
  778. }
  779. else
  780. {
  781. $msg = ($CI->lang->line($msg) == FALSE) ? $msg : $CI->lang->line($msg);
  782. $this->error_msg[] = $msg;
  783. log_message('error', $msg);
  784. }
  785. }
  786. // --------------------------------------------------------------------
  787. /**
  788. * Display the error message
  789. *
  790. * @param string
  791. * @param string
  792. * @return string
  793. */
  794. public function display_errors($open = '<p>', $close = '</p>')
  795. {
  796. $str = '';
  797. foreach ($this->error_msg as $val)
  798. {
  799. $str .= $open.$val.$close;
  800. }
  801. return $str;
  802. }
  803. // --------------------------------------------------------------------
  804. /**
  805. * List of Mime Types
  806. *
  807. * This is a list of mime types. We use it to validate
  808. * the "allowed types" set by the developer
  809. *
  810. * @param string
  811. * @return string
  812. */
  813. public function mimes_types($mime)
  814. {
  815. global $mimes;
  816. if (count($this->mimes) == 0)
  817. {
  818. if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/mimes.php'))
  819. {
  820. include(APPPATH.'config/'.ENVIRONMENT.'/mimes.php');
  821. }
  822. elseif (is_file(APPPATH.'config/mimes.php'))
  823. {
  824. include(APPPATH.'config//mimes.php');
  825. }
  826. else
  827. {
  828. return FALSE;
  829. }
  830. $this->mimes = $mimes;
  831. unset($mimes);
  832. }
  833. return ( ! isset($this->mimes[$mime])) ? FALSE : $this->mimes[$mime];
  834. }
  835. // --------------------------------------------------------------------
  836. /**
  837. * Prep Filename
  838. *
  839. * Prevents possible script execution from Apache's handling of files multiple extensions
  840. * http://httpd.apache.org/docs/1.3/mod/mod_mime.html#multipleext
  841. *
  842. * @param string
  843. * @return string
  844. */
  845. protected function _prep_filename($filename)
  846. {
  847. if (strpos($filename, '.') === FALSE OR $this->allowed_types == '*')
  848. {
  849. return $filename;
  850. }
  851. $parts = explode('.', $filename);
  852. $ext = array_pop($parts);
  853. $filename = array_shift($parts);
  854. foreach ($parts as $part)
  855. {
  856. if ( ! in_array(strtolower($part), $this->allowed_types) OR $this->mimes_types(strtolower($part)) === FALSE)
  857. {
  858. $filename .= '.'.$part.'_';
  859. }
  860. else
  861. {
  862. $filename .= '.'.$part;
  863. }
  864. }
  865. $filename .= '.'.$ext;
  866. return $filename;
  867. }
  868. // --------------------------------------------------------------------
  869. }
  870. // END Upload Class
  871. /* End of file Upload.php */
  872. /* Location: ./system/libraries/Upload.php */