2 /* vim: set expandtab sw=4 ts=4 sts=4: */
4 * file upload functions
12 * @todo replace error messages with localized string
13 * @todo when uploading a file into a blob field, should we also consider using
14 * chunks like in import? UPDATE `table` SET `field` = `field` + [chunk]
20 * @var string the temporary file name
26 * @var string the content
32 * @var string the error message
35 var $_error_message = '';
38 * @var bool whether the file is temporary or not
41 var $_is_temp = false;
44 * @var string type of compression
47 var $_compression = null;
55 * @var integer size of chunk to read with every step
57 var $_chunk_size = 32768;
60 * @var resource file handle
65 * @var boolean whether to decompress content before returning
67 var $_decompress = false;
70 * @var string charset of file
75 * @staticvar string most recent BLOB repository reference
77 static $_recent_bs_reference = NULL;
83 * @uses PMA_File::setName()
84 * @param string $name file name
86 function __construct($name = false)
89 $this->setName($name);
96 * @see PMA_File::cleanUp()
98 * @uses PMA_File::cleanUp()
100 function __destruct()
106 * deletes file if it is temporary, usally from a moved upload file
109 * @uses PMA_File::delet()
110 * @uses PMA_File::isTemp()
111 * @return boolean success
115 if ($this->isTemp()) {
116 return $this->delete();
126 * @uses PMA_File::getName()
128 * @return boolean success
132 return unlink($this->getName());
136 * checks or sets the temp flag for this file
137 * file objects with temp flags are deleted with object destruction
140 * @uses PMA_File::$_is_temp to set and read it
141 * @param boolean sets the temp flag
142 * @return boolean PMA_File::$_is_temp
144 function isTemp($is_temp = null)
146 if (null !== $is_temp) {
147 $this->_is_temp
= (bool) $is_temp;
150 return $this->_is_temp
;
157 * @uses PMA_File::$_name
158 * @param string $name file name
160 function setName($name)
162 $this->_name
= trim($name);
167 * @uses PMA_File::getName()
168 * @uses PMA_File::isUploaded()
169 * @uses PMA_File::checkUploadedFile()
170 * @uses PMA_File::isReadable()
171 * @uses PMA_File::$_content
172 * @uses function_exists()
173 * @uses file_get_contents()
178 * @return string binary file content
180 function getContent($as_binary = true, $offset = 0, $length = null)
182 if (null === $this->_content
) {
183 if ($this->isUploaded() && ! $this->checkUploadedFile()) {
187 if (! $this->isReadable()) {
191 if (function_exists('file_get_contents')) {
192 $this->_content
= file_get_contents($this->getName());
193 } elseif ($size = filesize($this->getName())) {
194 $this->_content
= fread(fopen($this->getName(), 'rb'), $size);
198 if (! empty($this->_content
) && $as_binary) {
199 return '0x' . bin2hex($this->_content
);
202 if (null !== $length) {
203 return substr($this->_content
, $offset, $length);
204 } elseif ($offset > 0) {
205 return substr($this->_content
, $offset);
208 return $this->_content
;
213 * @uses PMA_File::getName()
214 * @uses is_uploaded_file()
216 function isUploaded()
218 return is_uploaded_file($this->getName());
225 * @uses PMA_File::$name as return value
226 * @return string PMA_File::$_name
234 * @todo replace error message with localized string
236 * @uses PMA_File::isUploaded()
237 * @uses PMA_File::setName()
238 * @uses PMA_File::$_error_message
239 * @param string name of file uploaded
240 * @return boolean success
242 function setUploadedFile($name)
244 $this->setName($name);
246 if (! $this->isUploaded()) {
247 $this->setName(null);
248 $this->_error_message
= 'not an uploaded file';
257 * @uses PMA_File::fetchUploadedFromTblChangeRequestMultiple()
258 * @uses PMA_File::setUploadedFile()
259 * @uses PMA_File::setRecentBLOBReference()
260 * @uses curl_setopt_array()
261 * @uses PMA_File::$_error_message
262 * @uses __('The uploaded file exceeds the upload_max_filesize directive in php.ini.')
263 * @uses __('The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.')
264 * @uses __('The uploaded file was only partially uploaded.')
265 * @uses __('Missing a temporary folder.')
266 * @uses __('Failed to write file to disk.')
267 * @uses __('File upload stopped by extension.')
268 * @uses __('Unknown error in file upload.')
270 * @param string $key a numeric key used to identify the different rows
271 * @param string $primary_key
272 * @return boolean success
274 function setUploadedFromTblChangeRequest($key, $primary = null)
276 if (! isset($_FILES['fields_upload_' . $key])) {
280 $file = $_FILES['fields_upload_' . $key];
282 if (null !== $primary) {
283 $file = PMA_File
::fetchUploadedFromTblChangeRequestMultiple($file, $primary);
287 $is_bs_upload = FALSE;
289 // check if this field requires a repository upload
290 if (isset($_REQUEST['upload_blob_repo_' . $key]))
291 $is_bs_upload = ($_REQUEST['upload_blob_repo_' . $key]['multi_edit'][0] == "on") ?
TRUE : FALSE;
293 // if request is an upload to the BLOB repository
296 // load PMA configuration
297 $PMA_Config = $GLOBALS['PMA_Config'];
299 // if PMA configuration is loaded
300 if (!empty($PMA_Config))
302 // load BS variables from PMA configuration
303 $pluginsExist = $PMA_Config->get('BLOBSTREAMING_PLUGINS_EXIST');
304 $curlExists = $PMA_Config->get('CURL_EXISTS');
305 $bs_database = $PMA_Config->get('BLOBSTREAMABLE_DATABASES');
306 $bs_database = $bs_database[$_REQUEST['db']];
308 $allBSTablesExist = TRUE;
310 // determine if plugins and curl exist
311 if ($pluginsExist && $curlExists)
313 foreach ($bs_database as $table_key=>$table)
315 if (!$bs_database[$table_key]['Exists'])
317 $allBSTablesExist = FALSE;
323 $allBSTablesExist = FALSE;
325 // if necessary BS tables exist
326 if ($allBSTablesExist)
328 // setup bs variables for uploading
329 $bs_server = $PMA_Config->get('BLOBSTREAMING_SERVER');
330 $bs_db = $_REQUEST['db'];
331 $bs_table = $_REQUEST['table'];
333 // setup file handle and related variables
334 $tmp_file = fopen($file['tmp_name'], 'r');
335 $tmp_file_type = $file['type'];
336 $tmp_file_size = $file['size'];
339 $tmp_file_type = NULL;
341 // if none of the required variables contain data, return with an unknown error message
342 if (!$bs_server ||
!$bs_db ||
!$bs_table ||
!$tmp_file ||
!$tmp_file_size)
344 $this->_error_message
= __('Unknown error in file upload.');
348 $bs_server_path = 'http://' . $bs_server . '/' . $bs_db . '/' . $bs_table;
351 $curlHnd = curl_init ($bs_server_path);
353 // if curl handle init successful
356 // specify custom header
357 $customHeader = array(
358 "Accept-Language: en-us;en;q=0;5",
359 "Accept-Charset: ISO-8859-1;utf-8;q=0.7,*;q=0.7",
360 "Content-type: $tmp_file_type"
363 // specify CURL options in array
366 CURLOPT_HEADER
=> TRUE,
367 CURLOPT_HTTPHEADER
=> $customHeader,
368 CURLOPT_INFILESIZE
=> $tmp_file_size,
369 CURLOPT_INFILE
=> $tmp_file,
370 CURLOPT_RETURNTRANSFER
=> TRUE
373 // pass array of options to curl handle setup function
374 curl_setopt_array($curlHnd, $curlOptArr);
376 // execute curl request and retrieve error message(s) (if any)
377 $ret = curl_exec($curlHnd);
378 $errRet = curl_error($curlHnd);
381 curl_close($curlHnd);
383 // split entire string into array of lines
384 $retArr = explode("\r\n", $ret);
386 // check each line as a valid string of a BLOB reference
387 foreach ($retArr as $value)
388 if (strlen($value) > strlen("~*$bs_db/~") && "~*$bs_db/~" == substr($value, 0, strlen($bs_db) +
4))
390 // is a valid reference, so set as current and break
391 PMA_File
::setRecentBLOBReference($value);
398 } // end if ($curlHnd)
399 } // end if ($allBSTablesExist)
400 } // end if ($PMA_Config)
401 } // end if ($is_bs_upload)
403 // check for file upload errors
404 switch ($file['error']) {
405 // cybot_tm: we do not use the PHP constants here cause not all constants
406 // are defined in all versions of PHP - but the correct constants names
407 // are given as comment
408 case 0: //UPLOAD_ERR_OK:
409 return $this->setUploadedFile($file['tmp_name']);
411 case 4: //UPLOAD_ERR_NO_FILE:
413 case 1: //UPLOAD_ERR_INI_SIZE:
414 $this->_error_message
= __('The uploaded file exceeds the upload_max_filesize directive in php.ini.');
416 case 2: //UPLOAD_ERR_FORM_SIZE:
417 $this->_error_message
= __('The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.');
419 case 3: //UPLOAD_ERR_PARTIAL:
420 $this->_error_message
= __('The uploaded file was only partially uploaded.');
422 case 6: //UPLOAD_ERR_NO_TMP_DIR:
423 $this->_error_message
= __('Missing a temporary folder.');
425 case 7: //UPLOAD_ERR_CANT_WRITE:
426 $this->_error_message
= __('Failed to write file to disk.');
428 case 8: //UPLOAD_ERR_EXTENSION:
429 $this->_error_message
= __('File upload stopped by extension.');
432 $this->_error_message
= __('Unknown error in file upload.');
439 * strips some dimension from the multi-dimensional array from $_FILES
442 * $file['name']['multi_edit'][$primary] = [value]
443 * $file['type']['multi_edit'][$primary] = [value]
444 * $file['size']['multi_edit'][$primary] = [value]
445 * $file['tmp_name']['multi_edit'][$primary] = [value]
446 * $file['error']['multi_edit'][$primary] = [value]
450 * $file['name'] = [value]
451 * $file['type'] = [value]
452 * $file['size'] = [value]
453 * $file['tmp_name'] = [value]
454 * $file['error'] = [value]
457 * @todo re-check if requirements changes to PHP >= 4.2.0
460 * @param array $file the array
461 * @param string $primary
464 function fetchUploadedFromTblChangeRequestMultiple($file, $primary)
467 'name' => $file['name']['multi_edit'][$primary],
468 'type' => $file['type']['multi_edit'][$primary],
469 'size' => $file['size']['multi_edit'][$primary],
470 'tmp_name' => $file['tmp_name']['multi_edit'][$primary],
471 'error' => $file['error']['multi_edit'][$primary],
478 * sets the name if the file to the one selected in the tbl_change form
482 * @uses PMA_File::setLocalSelectedFile()
484 * @param string $key a numeric key used to identify the different rows
485 * @param string $primary_key
486 * @return boolean success
488 function setSelectedFromTblChangeRequest($key, $primary = null)
490 if (null !== $primary) {
491 if (! empty($_REQUEST['fields_uploadlocal_' . $key]['multi_edit'][$primary])
492 && is_string($_REQUEST['fields_uploadlocal_' . $key]['multi_edit'][$primary])) {
493 // ... whether with multiple rows ...
495 $is_bs_upload = FALSE;
497 // check if this field requires a repository upload
498 if (isset($_REQUEST['upload_blob_repo_' . $key]))
499 $is_bs_upload = ($_REQUEST['upload_blob_repo_' . $key]['multi_edit'][0] == "on") ?
TRUE : FALSE;
501 // is a request to upload file to BLOB repository using uploadDir mechanism
504 // load PMA configuration
505 $PMA_Config = $GLOBALS['PMA_Config'];
507 // if the PMA configuration was loaded
508 if (!empty($PMA_Config))
510 // load BS variables from PMA configuration
511 $pluginsExist = $PMA_Config->get('BLOBSTREAMING_PLUGINS_EXIST');
512 $curlExists = $PMA_Config->get('CURL_EXISTS');
513 $bs_database = $PMA_Config->get('BLOBSTREAMABLE_DATABASES');
514 $bs_database = $bs_database[$_REQUEST['db']];
516 $allBSTablesExist = TRUE;
518 // if plugins and curl exist
519 if ($pluginsExist && $curlExists)
521 foreach ($bs_database as $table_key=>$table)
523 if (!$bs_database[$table_key]['Exists'])
525 $allBSTablesExist = FALSE;
531 $allBSTablesExist = FALSE;
533 // if necessary BS tables exist
534 if ($allBSTablesExist)
537 $bs_server = $PMA_Config->get('BLOBSTREAMING_SERVER');
538 $bs_db = $_REQUEST['db'];
539 $bs_table = $_REQUEST['table'];
541 // setup uploadDir mechanism and file variables
542 $tmp_filename = $GLOBALS['cfg']['UploadDir'] . '/' . $_REQUEST['fields_uploadlocal_' . $key]['multi_edit'][$primary];
543 $tmp_file = fopen($tmp_filename, 'r');
544 $tmp_file_size = filesize($tmp_filename);
546 // check if fileinfo library exists
547 if ($PMA_Config->get('FILEINFO_EXISTS'))
549 // attempt to init fileinfo
550 $finfo = finfo_open(FILEINFO_MIME
);
555 // pass in filename to fileinfo and close fileinfo handle after
556 $tmp_file_type = finfo_file($finfo, $tmp_filename);
560 else // no fileinfo library exists, use file command
561 $tmp_file_type = exec("file -bi " . escapeshellarg($tmp_filename));
564 $tmp_file_type = NULL;
566 // necessary variables aren't loaded, return error message (unknown error)
567 if (!$bs_server ||
!$bs_db ||
!$bs_table ||
!$tmp_file ||
!$tmp_file_size)
569 $this->_error_message
= __('Unknown error in file upload.');
573 $bs_server_path = 'http://' . $bs_server . '/' . $bs_db . '/' . $bs_table;
576 $curlHnd = curl_init ($bs_server_path);
578 // curl handle exists
581 // specify custom header
582 $customHeader = array(
583 "Accept-Language: en-us;en;q=0;5",
584 "Accept-Charset: ISO-8859-1;utf-8;q=0.7,*;q=0.7",
585 "Content-type: $tmp_file_type"
588 // specify custom curl options
591 CURLOPT_HEADER
=> TRUE,
592 CURLOPT_HTTPHEADER
=> $customHeader,
593 CURLOPT_INFILESIZE
=> $tmp_file_size,
594 CURLOPT_INFILE
=> $tmp_file,
595 CURLOPT_RETURNTRANSFER
=> TRUE
598 // setup custom curl options (as specified in above array)
599 curl_setopt_array($curlHnd, $curlOptArr);
601 // execute curl request and retrieve error message(s) (if any)
602 $ret = curl_exec($curlHnd);
603 $errRet = curl_error($curlHnd);
606 curl_close($curlHnd);
608 // split return string into lines
609 $retArr = explode("\r\n", $ret);
611 // check subsequent lines for valid BLOB reference string
612 foreach ($retArr as $value)
613 if (strlen($value) > strlen("~*$bs_db/~") && "~*$bs_db/~" == substr($value, 0, strlen($bs_db) +
4))
615 // is a valid reference, so set as current and break
616 PMA_File
::setRecentBLOBReference($value);
623 } // end if ($curlHnd)
624 } // end if ($allBSTablesExist)
625 } // end if ($PMA_Config)
626 } // end if ($is_bs_upload)
628 return $this->setLocalSelectedFile($_REQUEST['fields_uploadlocal_' . $key]['multi_edit'][$primary]);
632 } elseif (! empty($_REQUEST['fields_uploadlocal_' . $key])
633 && is_string($_REQUEST['fields_uploadlocal_' . $key])) {
635 $is_bs_upload = FALSE;
637 // check if this field requires a repository upload
638 if (isset($_REQUEST['upload_blob_repo_' . $key]))
639 $is_bs_upload = ($_REQUEST['upload_blob_repo_' . $key]['multi_edit'][0] == "on") ?
TRUE : FALSE;
641 // is a request to upload file to BLOB repository using uploadDir mechanism
644 // load PMA configuration
645 $PMA_Config = $GLOBALS['PMA_Config'];
647 // if the PMA configuration was loaded
648 if (!empty($PMA_Config))
650 // load BS variables from PMA configuration
651 $pluginsExist = $PMA_Config->get('BLOBSTREAMING_PLUGINS_EXIST');
652 $curlExists = $PMA_Config->get('CURL_EXISTS');
653 $bs_database = $PMA_Config->get('BLOBSTREAMABLE_DATABASES');
654 $bs_database = $bs_database[$_REQUEST['db']];
656 $allBSTablesExist = TRUE;
658 // if plugins and curl exist
659 if ($pluginsExist && $curlExists)
661 foreach ($bs_database as $table_key=>$table)
663 if (!$bs_database[$table_key]['Exists'])
665 $allBSTablesExist = FALSE;
671 $allBSTablesExist = FALSE;
673 if ($allBSTablesExist)
676 $bs_server = $PMA_Config->get('BLOBSTREAMING_SERVER');
677 $bs_db = $_REQUEST['db'];
678 $bs_table = $_REQUEST['table'];
680 // setup uploadDir mechanism and file variables
681 $tmp_filename = $GLOBALS['cfg']['UploadDir'] . '/' . $_REQUEST['fields_uploadlocal_' . $key]['multi_edit'][$primary];
682 $tmp_file = fopen($tmp_filename, 'r');
683 $tmp_file_size = filesize($tmp_filename);
685 // check if fileinfo library exists
686 if ($PMA_Config->get('FILEINFO_EXISTS'))
688 // attempt to init fileinfo
689 $finfo = finfo_open(FILEINFO_MIME
);
691 // if fileinfo exists
694 // pass in filename to fileinfo and close fileinfo handle after
695 $tmp_file_type = finfo_file($finfo, $tmp_filename);
699 else // no fileinfo library exists, use file command
700 $tmp_file_type = exec("file -bi " . escapeshellarg($tmp_filename));
703 $tmp_file_type = NULL;
705 // necessary variables aren't loaded, return error message (unknown error)
706 if (!$bs_server ||
!$bs_db ||
!$bs_table ||
!$tmp_file ||
!$tmp_file_size)
708 $this->_error_message
= __('Unknown error in file upload.');
712 $bs_server_path = 'http://' . $bs_server . '/' . $bs_db . '/' . $bs_table;
715 $curlHnd = curl_init ($bs_server_path);
717 // if curl handle exists
720 // specify custom header
721 $customHeader = array(
722 "Accept-Language: en-us;en;q=0;5",
723 "Accept-Charset: ISO-8859-1;utf-8;q=0.7,*;q=0.7",
724 "Content-type: $tmp_file_type"
727 // specify custom curl options
730 CURLOPT_HEADER
=> TRUE,
731 CURLOPT_HTTPHEADER
=> $customHeader,
732 CURLOPT_INFILESIZE
=> $tmp_file_size,
733 CURLOPT_INFILE
=> $tmp_file,
734 CURLOPT_RETURNTRANSFER
=> TRUE
737 // setup custom curl options (as specified in above array)
738 curl_setopt_array($curlHnd, $curlOptArr);
740 // execute curl request and retrieve error message(s) (if any)
741 $ret = curl_exec($curlHnd);
742 $errRet = curl_error($curlHnd);
745 curl_close($curlHnd);
747 // split return string into lines
748 $retArr = explode("\r\n", $ret);
750 // check subsequent lines for valid BLOB reference string
751 foreach ($retArr as $value)
752 if (strlen($value) > strlen("~*$bs_db/~") && "~*$bs_db/~" == substr($value, 0, strlen($bs_db) +
4))
754 // is a valid reference, so set as current and break
755 PMA_File
::setRecentBLOBReference($value);
762 } // end if ($curlHnd)
763 } // end if ($allBSTablesExist)
764 } // end if ($PMA_Config)
765 } // end if ($is_bs_upload)
767 return $this->setLocalSelectedFile($_REQUEST['fields_uploadlocal_' . $key]);
775 * @uses PMA_File->$_error_message as return value
776 * @return string error message
780 return $this->_error_message
;
785 * @uses PMA_File->$_error_message to check it
786 * @return boolean whether an error occured or not
790 return ! empty($this->_error_message
);
794 * checks the superglobals provided if the tbl_change form is submitted
795 * and uses the submitted/selected file
798 * @uses PMA_File::setUploadedFromTblChangeRequest()
799 * @uses PMA_File::setSelectedFromTblChangeRequest()
800 * @param string $key a numeric key used to identify the different rows
801 * @param string $primary_key
802 * @return boolean success
804 function checkTblChangeForm($key, $primary_key)
806 if ($this->setUploadedFromTblChangeRequest($key, $primary_key)) {
808 $this->_error_message
= '';
811 } elseif ($this->setUploadedFromTblChangeRequest($key)) {
813 $this->_error_message = '';
816 } elseif ($this->setSelectedFromTblChangeRequest($key, $primary_key)) {
818 $this->_error_message
= '';
821 } elseif ($this->setSelectedFromTblChangeRequest($key)) {
823 $this->_error_message = '';
827 // all failed, whether just no file uploaded/selected or an error
835 * @uses __('File could not be read')
836 * @uses PMA_File::setName()
837 * @uses PMA_securePath()
838 * @uses PMA_userDir()
839 * @uses $GLOBALS['cfg']['UploadDir']
840 * @param string $name
841 * @return boolean success
843 function setLocalSelectedFile($name)
845 if (empty($GLOBALS['cfg']['UploadDir'])) return false;
847 $this->setName(PMA_userDir($GLOBALS['cfg']['UploadDir']) . PMA_securePath($name));
848 if (! $this->isReadable()) {
849 $this->_error_message
= __('File could not be read');
850 $this->setName(null);
859 * @uses PMA_File::getName()
860 * @uses is_readable()
862 * @uses ob_end_clean()
863 * @return boolean whether the file is readable or not
865 function isReadable()
867 // suppress warnings from being displayed, but not from being logged
868 // any file access outside of open_basedir will issue a warning
870 $is_readable = is_readable($this->getName());
876 * If we are on a server with open_basedir, we must move the file
877 * before opening it. The FAQ 1.11 explains how to create the "./tmp"
878 * directory - if needed
880 * @todo replace error message with localized string
881 * @todo move check of $cfg['TempDir'] into PMA_Config?
883 * @uses $cfg['TempDir']
884 * @uses __('Error moving the uploaded file, see [a@./Documentation.html#faq1_11@Documentation]FAQ 1.11[/a]')
885 * @uses PMA_File::isReadable()
886 * @uses PMA_File::getName()
887 * @uses PMA_File::setName()
888 * @uses PMA_File::isTemp()
889 * @uses PMA_File::$_error_message
893 * @uses is_writable()
895 * @uses move_uploaded_file()
897 * @uses ob_end_clean()
898 * @return boolean whether uploaded fiel is fine or not
900 function checkUploadedFile()
902 if ($this->isReadable()) {
906 if (empty($GLOBALS['cfg']['TempDir']) ||
! is_writable($GLOBALS['cfg']['TempDir'])) {
907 // cannot create directory or access, point user to FAQ 1.11
908 $this->_error_message
= __('Error moving the uploaded file, see [a@./Documentation.html#faq1_11@Documentation]FAQ 1.11[/a]');
912 $new_file_to_upload = tempnam(realpath($GLOBALS['cfg']['TempDir']), basename($this->getName()));
914 // suppress warnings from being displayed, but not from being logged
915 // any file access outside of open_basedir will issue a warning
917 $move_uploaded_file_result = move_uploaded_file($this->getName(), $new_file_to_upload);
919 if (! $move_uploaded_file_result) {
920 $this->_error_message
= 'error while moving uploaded file';
924 $this->setName($new_file_to_upload);
927 if (! $this->isReadable()) {
928 $this->_error_message
= 'cannot read (moved) upload file';
936 * Detects what compression filse uses
938 * @todo move file read part into readChunk() or getChunk()
939 * @todo add support for compression plugins
940 * @uses __('File could not be read')
941 * @uses PMA_File::$_compression to set it
942 * @uses PMA_File::getName()
950 * @return string MIME type of compression, none for none
952 function _detectCompression()
954 // suppress warnings from being displayed, but not from being logged
955 // f.e. any file access outside of open_basedir will issue a warning
957 $file = fopen($this->getName(), 'rb');
961 $this->_error_message
= __('File could not be read');
967 * get registered plugins for file compression
969 foreach (PMA_getPlugins($type = 'compression') as $plugin) {
970 if (call_user_func_array(array($plugin['classname'], 'canHandle'), array($this->getName()))) {
971 $this->setCompressionPlugin($plugin);
977 $test = fread($file, 4);
978 $len = strlen($test);
981 if ($len >= 2 && $test[0] == chr(31) && $test[1] == chr(139)) {
982 $this->_compression
= 'application/gzip';
983 } elseif ($len >= 3 && substr($test, 0, 3) == 'BZh') {
984 $this->_compression
= 'application/bzip2';
985 } elseif ($len >= 4 && $test == "PK\003\004") {
986 $this->_compression
= 'application/zip';
988 $this->_compression
= 'none';
991 return $this->_compression
;
995 * whether the content should be decompressed before returned
997 function setDecompressContent($decompress)
999 $this->_decompress
= (bool) $decompress;
1002 function getHandle()
1004 if (null === $this->_handle
) {
1007 return $this->_handle
;
1010 function setHandle($handle)
1012 $this->_handle
= $handle;
1020 if (! $this->_decompress
) {
1021 $this->_handle
= @fopen
($this->getName(), 'r');
1024 switch ($this->getCompression()) {
1027 case 'application/bzip2':
1028 if ($GLOBALS['cfg']['BZipDump'] && @function_exists
('bzopen')) {
1029 $this->_handle
= @bzopen
($this->getName(), 'r');
1031 $this->_error_message
= sprintf(__('You attempted to load file with unsupported compression (%s). Either support for it is not implemented or disabled by your configuration.'), $this->getCompression());
1035 case 'application/gzip':
1036 if ($GLOBALS['cfg']['GZipDump'] && @function_exists
('gzopen')) {
1037 $this->_handle
= @gzopen
($this->getName(), 'r');
1039 $this->_error_message
= sprintf(__('You attempted to load file with unsupported compression (%s). Either support for it is not implemented or disabled by your configuration.'), $this->getCompression());
1043 case 'application/zip':
1044 if ($GLOBALS['cfg']['ZipDump'] && @function_exists
('zip_open')) {
1045 include_once './libraries/zip_extension.lib.php';
1046 $result = PMA_getZipContents($this->getName());
1047 if (! empty($result['error'])) {
1048 $this->_error_message
= PMA_Message
::rawError($result['error']);
1051 $this->content_uncompressed
= $result['data'];
1055 $this->_error_message
= sprintf(__('You attempted to load file with unsupported compression (%s). Either support for it is not implemented or disabled by your configuration.'), $this->getCompression());
1060 $this->_handle
= @fopen
($this->getName(), 'r');
1063 $this->_error_message
= sprintf(__('You attempted to load file with unsupported compression (%s). Either support for it is not implemented or disabled by your configuration.'), $this->getCompression());
1071 function getCharset()
1073 return $this->_charset
;
1076 function setCharset($charset)
1078 $this->_charset
= $charset;
1082 * @uses PMA_File::$_compression as return value
1083 * @uses PMA_File::detectCompression()
1084 * @return string MIME type of compression, none for none
1087 function getCompression()
1089 if (null === $this->_compression
) {
1090 return $this->_detectCompression();
1093 return $this->_compression
;
1097 * advances the file pointer in the file handle by $length bytes/chars
1099 * @param integer $length numbers of chars/bytes to skip
1101 * @todo this function is unused
1103 function advanceFilePointer($length)
1105 while ($length > 0) {
1106 // Disable read progresivity, otherwise we eat all memory!
1107 $read_multiply = 1; // required?
1108 $this->getNextChunk($length);
1109 $length -= $this->getChunkSize();
1114 * http://bugs.php.net/bug.php?id=29532
1115 * bzip reads a maximum of 8192 bytes on windows systems
1116 * @todo this function is unused
1118 function getNextChunk($max_size = null)
1120 if (null !== $max_size) {
1121 $size = min($max_size, $this->getChunkSize());
1123 $size = $this->getChunkSize();
1126 // $result = $this->handler->getNextChunk($size);
1128 switch ($this->getCompression()) {
1129 case 'application/bzip2':
1131 while (strlen($result) < $size - 8192 && ! feof($this->getHandle())) {
1132 $result .= bzread($this->getHandle(), $size);
1135 case 'application/gzip':
1136 $result = gzread($this->getHandle(), $size);
1138 case 'application/zip':
1140 * if getNextChunk() is used some day,
1141 * replace this code by code similar to the one
1144 include_once './libraries/unzip.lib.php';
1145 $import_handle = new SimpleUnzip();
1146 $import_handle->ReadFile($this->getName());
1147 if ($import_handle->Count() == 0) {
1148 $this->_error_message = __('No files found inside ZIP archive!');
1150 } elseif ($import_handle->GetError(0) != 0) {
1151 $this->_error_message = __('Error in ZIP archive:')
1152 . ' ' . $import_handle->GetErrorMsg(0);
1155 $result = $import_handle->GetData(0);
1160 $result = fread($this->getHandle(), $size);
1167 echo strlen($result) . ' - ';
1168 echo (@$GLOBALS['__len__'] +
= strlen($result)) . ' - ';
1169 echo $this->_error_message
;
1172 if ($GLOBALS['charset_conversion']) {
1173 $result = PMA_convert_string($this->getCharset(), $GLOBALS['charset'], $result);
1176 * Skip possible byte order marks (I do not think we need more
1177 * charsets, but feel free to add more, you can use wikipedia for
1178 * reference: <http://en.wikipedia.org/wiki/Byte_Order_Mark>)
1180 * @todo BOM could be used for charset autodetection
1182 if ($this->getOffset() === 0) {
1184 if (strncmp($result, "\xEF\xBB\xBF", 3) == 0) {
1185 $result = substr($result, 3);
1187 } elseif (strncmp($result, "\xFE\xFF", 2) == 0
1188 ||
strncmp($result, "\xFF\xFE", 2) == 0) {
1189 $result = substr($result, 2);
1194 $this->_offset +
= $size;
1195 if (0 === $result) {
1201 function getOffset()
1203 return $this->_offset
;
1206 function getChunkSize()
1208 return $this->_chunk_size
;
1211 function setChunkSize($chunk_size)
1213 $this->_chunk_size
= (int) $chunk_size;
1216 function getContentLength()
1218 return strlen($this->_content
);
1223 if ($this->getHandle()) {
1224 return feof($this->getHandle());
1226 return ($this->getOffset() >= $this->getContentLength());
1232 * sets reference to most recent BLOB repository reference
1235 * @param string - BLOB repository reference
1237 static function setRecentBLOBReference($ref)
1239 PMA_File
::$_recent_bs_reference = $ref;
1243 * retrieves reference to most recent BLOB repository reference
1246 * @return string - most recent BLOB repository reference
1248 static function getRecentBLOBReference()
1250 $ref = PMA_File
::$_recent_bs_reference;
1251 PMA_File
::$_recent_bs_reference = NULL;