1<?php 2/** 3 * DokuWiki Plugin PreserveFilenames / common.php 4 * 5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6 * @author Kazutaka Miyasaka <kazmiya@gmail.com> 7 */ 8 9// must be run within DokuWiki 10if (!defined('DOKU_INC')) { 11 die(); 12} 13 14class PreserveFilenames_Common 15{ 16 /** 17 * Returns a correct basename 18 * (fixes PHP Bug #37738: basename() bug in handling multibyte filenames) 19 * 20 * @see http://bugs.php.net/37738 21 */ 22 function _correctBasename($path) 23 { 24 return rawurldecode(basename(preg_replace_callback( 25 '/%(?:[013-7][0-9a-fA-F]|2[0-46-9a-fA-F])/', // ASCII except for '%' 26 array(self, '_correctBasename_callback'), 27 rawurlencode($path) 28 ))); 29 } 30 31 /** 32 * Callback function for _correctBasename() (only does rawurldecode) 33 */ 34 static function _correctBasename_callback($matches) 35 { 36 return rawurldecode($matches[0]); 37 } 38 39 /** 40 * Returns a sanitized safe filename 41 * 42 * @see http://en.wikipedia.org/wiki/Filename 43 */ 44 function _sanitizeFileName($filename) 45 { 46 $filename = preg_replace('/[\x00-\x1F\x7F]/', '', $filename); // control 47 $filename = preg_replace('/["*:<>?|\/\\\\]/', '_', $filename); // graphic 48 $filename = preg_replace('/[#&]/', '_', $filename); // dw technical issues 49 50 return $filename; 51 } 52 53 /** 54 * Builds appropriate "Content-Disposition" header strings 55 * 56 * @see http://greenbytes.de/tech/tc2231/ 57 */ 58 function _buildContentDispositionHeader($download, $filename, $no_pathinfo = false) 59 { 60 global $conf; 61 62 $ua = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : ''; 63 $type = $download ? 'attachment' : 'inline'; 64 $ret = "Content-Disposition: $type;"; 65 66 if (!preg_match('/[\x00-\x1F\x7F-\xFF"*:<>?|\/\\\\]/', $filename)) { 67 // no problem with filename-safe ascii characters 68 $ret .= ' filename="' . $filename . '";'; 69 } elseif (preg_match('/(?:Gecko\/|Opera\/| Opera )/', $ua)) { 70 // use RFC2231 if accessed via RFC2231-compliant browser 71 $ret .= " filename*=UTF-8''" . rawurlencode($filename) . ';'; 72 } elseif ( 73 strpos($filename, '"') === false 74 && strpos($ua, 'Safari/') !== false 75 && strpos($ua, 'Chrome/') === false 76 && preg_match('/Version\/[4-9]/', $ua) 77 && !preg_match('/Mac OS X 10_[1-4]_/', $ua) 78 ) { 79 // raw UTF-8 quoted-string 80 $ret .= ' filename="' . $filename . '"'; 81 } elseif ( 82 !$no_pathinfo 83 && $conf['useslash'] 84 && $conf['userewrite'] 85 && strpos($ua, 'Safari/') !== false 86 && strpos($ua, 'Chrome/') === false 87 ) { 88 // leave filename-parm field empty 89 // (browsers can retrieve a filename from pathinfo of its url) 90 } else { 91 // fallback to the DokuWiki default 92 $ret .= ' filename="' . rawurlencode($filename) . '";'; 93 } 94 95 return $ret; 96 } 97} 98