forked from extern/egroupware
Fix vCard export issue
This commit is contained in:
parent
8fec4d6b94
commit
4962c59833
@ -969,8 +969,7 @@ class addressbook_vcal extends addressbook_bo
|
||||
{
|
||||
if (!$file)
|
||||
{
|
||||
$browser =& CreateObject('phpgwapi.browser');
|
||||
$browser->content_header('addressbook.vcf','text/x-vcard');
|
||||
html::content_header('addressbook.vcf','text/x-vcard');
|
||||
}
|
||||
if (!($fp = fopen($file ? $file : 'php://output','w')))
|
||||
{
|
||||
|
@ -6,7 +6,7 @@
|
||||
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de> complete rewrite in 6/2006 and earlier modifications
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @author RalfBecker-AT-outdoor-training.de
|
||||
* @copyright 2001-2008 by RalfBecker@outdoor-training.de
|
||||
* @copyright 2001-2009 by RalfBecker@outdoor-training.de
|
||||
* @package api
|
||||
* @subpackage html
|
||||
* @version $Id$
|
||||
@ -15,13 +15,12 @@
|
||||
/**
|
||||
* Generates html with methods representing html-tags or higher widgets
|
||||
*
|
||||
* The class has only static methods now, so there's no need to instanciate the object anymore!
|
||||
*
|
||||
* The class has only static methods now, so there's no need to instanciate as object anymore!
|
||||
*/
|
||||
class html
|
||||
{
|
||||
/**
|
||||
* user-agent: 'mozilla','msie','konqueror', 'safari', 'opera'
|
||||
* user-agent: 'firefox', 'msie', 'safari' (incl. iPhone, Chrome), 'opera', 'konqueror', 'mozilla'
|
||||
* @var string
|
||||
*/
|
||||
static $user_agent;
|
||||
@ -58,17 +57,17 @@ class html
|
||||
static function _init_static()
|
||||
{
|
||||
// should be Ok for all HTML 4 compatible browsers
|
||||
if (!preg_match('/(Safari)\/([0-9.]+)/i',$_SERVER['HTTP_USER_AGENT'],$parts) &&
|
||||
!preg_match('/compatible; ([a-z_]+)[\/ ]+([0-9.]+)/i',$_SERVER['HTTP_USER_AGENT'],$parts))
|
||||
if(!preg_match('/compatible; ([a-z]+)[\/ ]+([0-9.]+)/i',$_SERVER['HTTP_USER_AGENT'],$parts))
|
||||
{
|
||||
preg_match('/^([a-z_]+)\/([0-9.]+)/i',$_SERVER['HTTP_USER_AGENT'],$parts);
|
||||
preg_match_all('/([a-z]+)\/([0-9.]+)/i',$_SERVER['HTTP_USER_AGENT'],$parts,PREG_SET_ORDER);
|
||||
$parts = array_pop($parts);
|
||||
}
|
||||
list(,self::$user_agent,self::$ua_version) = $parts;
|
||||
self::$user_agent = strtolower(self::$user_agent);
|
||||
if ((self::$user_agent = strtolower(self::$user_agent)) == 'version') self::$user_agent = 'opera';
|
||||
|
||||
self::$netscape4 = self::$user_agent == 'mozilla' && self::$ua_version < 5;
|
||||
self::$prefered_img_title = self::$netscape4 ? 'alt' : 'title';
|
||||
//echo "<p>HTTP_USER_AGENT='$_SERVER[HTTP_USER_AGENT]', UserAgent: 'self::$user_agent', Version: 'self::$ua_version', img_title: 'self::$prefered_img_title'</p>\n";
|
||||
//echo "<p>HTTP_USER_AGENT='$_SERVER[HTTP_USER_AGENT]', UserAgent: '".self::$user_agent."', Version: '".self::$ua_version."', img_title: '".self::$prefered_img_title."'</p>\n";
|
||||
|
||||
if ($GLOBALS['egw']->translation)
|
||||
{
|
||||
@ -80,7 +79,7 @@ class html
|
||||
/**
|
||||
* Created an input-field with an attached color-picker
|
||||
*
|
||||
* Please note: it need to be called before the call to phpgw_header() !!!
|
||||
* Please note: it need to be called before the call to egw_header() !!!
|
||||
*
|
||||
* @param string $name the name of the input-field
|
||||
* @param string $value the actual value for the input-field, default ''
|
||||
@ -90,8 +89,8 @@ class html
|
||||
static function inputColor($name,$value='',$title='')
|
||||
{
|
||||
$id = str_replace(array('[',']'),array('_',''),$name).'_colorpicker';
|
||||
$onclick = "javascript:window.open('".self::$api_js_url.'/colorpicker/select_color.html?id='.urlencode($id)."&color='+document.getElementById('$id').value,'colorPicker','width=240,height=187,scrollbars=no,resizable=no,toolbar=no');";
|
||||
return '<input type="text" name="'.$name.'" id="'.$id.'" value="'.self::htmlspecialchars($value).'" /> '.
|
||||
$onclick = "javascript:window.open('".self::$api_js_url.'/colorpicker/select_color.html?id='.urlencode($id)."&color='+encodeURIComponent(document.getElementById('$id').value),'colorPicker','width=240,height=187,scrollbars=no,resizable=no,toolbar=no');";
|
||||
return '<input type="text" name="'.$name.'" id="'.$id.'" value="'.self::htmlspecialchars($value).'" size="7" maxsize="7" /> '.
|
||||
'<a href="#" onclick="'.$onclick.'">'.
|
||||
'<img src="'.self::$api_js_url.'/colorpicker/ed_color_bg.gif'.'"'.($title ? ' title="'.self::htmlspecialchars($title).'"' : '')." /></a>";
|
||||
}
|
||||
@ -101,8 +100,7 @@ class html
|
||||
*
|
||||
* Note: The wz_tooltip.js file gets automaticaly loaded at the end of the page
|
||||
*
|
||||
* @param string/boolean $text text or html for the tooltip, all chars allowed, they will be quoted approperiate
|
||||
* Or if False the content (innerHTML) of the element itself is used.
|
||||
* @param string $text text or html for the tooltip, all chars allowed, they will be quoted approperiate
|
||||
* @param boolean $do_lang (default False) should the text be run though lang()
|
||||
* @param array $options param/value pairs, eg. 'TITLE' => 'I am the title'. Some common parameters:
|
||||
* title (string) gives extra title-row, width (int,'auto') , padding (int), above (bool), bgcolor (color), bgimg (URL)
|
||||
@ -111,28 +109,35 @@ class html
|
||||
*/
|
||||
static function tooltip($text,$do_lang=False,$options=False)
|
||||
{
|
||||
if (!self::$wz_tooltip_included)
|
||||
{
|
||||
if (strpos($GLOBALS['egw_info']['flags']['need_footer'],'wz_tooltip')===false)
|
||||
{
|
||||
$GLOBALS['egw_info']['flags']['need_footer'] .= '<script language="JavaScript" type="text/javascript" src="'.self::$api_js_url.'/wz_tooltip/wz_tooltip.js"></script>'."\n";
|
||||
}
|
||||
self::$wz_tooltip_included = True;
|
||||
}
|
||||
if ($do_lang) $text = lang($text);
|
||||
|
||||
$opt_out = 'this.T_WIDTH = 200;';
|
||||
$ttip = ' onmouseover="Tip(\''.str_replace(array("\n","\r","'",'"'),array('','',"\\'",'"'),$text).'\'';
|
||||
|
||||
$sticky = false;
|
||||
if (is_array($options))
|
||||
{
|
||||
foreach($options as $option => $value)
|
||||
{
|
||||
$opt_out .= 'this.T_'.strtoupper($option).'='.(is_bool($value)?($value?'true':'false'):
|
||||
(is_numeric($value)?$value:"'".str_replace(array("'",'"'),array("\\'",'"'),$value)."'")).'; ';
|
||||
$option = strtoupper($option);
|
||||
if ($option == 'STICKY') $sticky = (bool)$value;
|
||||
|
||||
switch(gettype($value))
|
||||
{
|
||||
case 'boolean':
|
||||
$value = $value ? 'true' : 'false';
|
||||
break;
|
||||
case 'string':
|
||||
if (stripos($value,"'")===false) $value = "'$value'";
|
||||
break;
|
||||
}
|
||||
$ttip .= ','.$option.','.$value;
|
||||
}
|
||||
}
|
||||
if ($text === False) return ' onmouseover="'.$opt_out.'return escape(this.innerHTML);"';
|
||||
$ttip .= ')"';
|
||||
|
||||
return ' onmouseover="'.$opt_out.'return escape(\''.str_replace(array("\n","\r","'",'"'),array('','',"\\'",'"'),$text).'\')"';
|
||||
$ttip .= ' onmouseout="UnTip()"';
|
||||
|
||||
return $ttip;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -144,7 +149,7 @@ class html
|
||||
static function activate_links($content)
|
||||
{
|
||||
if (!$content || strlen($content) < 20) return $content; // performance
|
||||
|
||||
|
||||
// Exclude everything which is already a link
|
||||
$NotAnchor = '(?<!"|href=|href\s=\s|href=\s|href\s=)';
|
||||
|
||||
@ -170,6 +175,97 @@ class html
|
||||
return preg_replace( $Expr, "<a href=\"http://$0\" target=\"_blank\">$0</a>", $result );
|
||||
}
|
||||
|
||||
/**
|
||||
* activates URLs in a text, URLs get replaced by html-links using htmlpurify
|
||||
*
|
||||
* @param string $content text containing URLs
|
||||
* @return string html with activated links
|
||||
*/
|
||||
static function activateLinks($content)
|
||||
{
|
||||
if (!$content || strlen($content) < 20) return $content; // performance
|
||||
|
||||
// spamsaver emailaddress
|
||||
$result = preg_replace('/'.$NotAnchor.'mailto:([a-z0-9._-]+)@([a-z0-9_-]+)\.([a-z0-9._-]+)/i',
|
||||
'<a href="#" onclick="document.location=\'mai\'+\'lto:\\1\'+unescape(\'%40\')+\'\\2.\\3\'; return false;">\\1 AT \\2 DOT \\3</a>',
|
||||
$content);
|
||||
|
||||
$config = self::purifyCreateDefaultConfig();
|
||||
$config->set('Core.Encoding', (self::$charset?self::$charset:'UTF-8'));
|
||||
// maybe the two following lines are useful for caching???
|
||||
$config->set('HTML.DefinitionID', 'activatelinks');
|
||||
$config->set('HTML.DefinitionRev', 1);
|
||||
// doctype and tidylevel
|
||||
$config->set('HTML.Doctype', 'XHTML 1.0 Transitional');
|
||||
$config->set('HTML.TidyLevel', 'light');
|
||||
// EnableID is needed for anchor tags
|
||||
$config->set('Attr.EnableID',true);
|
||||
// actual allowed tags and attributes
|
||||
$config->set('URI.AllowedSchemes', array('http'=>true, 'https'=>true, 'ftp'=>true, 'file'=>true, 'cid'=>true));
|
||||
$config->set('AutoFormat.RemoveEmpty', true);
|
||||
$config->set('HTML.Allowed', 'br,p[align],b,i,u,s,em,pre,tt,strong,strike,center,div[align],hr[class|style],'.
|
||||
'font[size|color],'.
|
||||
'ul[type],ol[type|start],li,'.
|
||||
'h1,h2,h3,'.
|
||||
'span[class|style],'.
|
||||
'table[class|border|cellpadding|cellspacing|width|style|align|bgcolor|align],'.
|
||||
'tbody,thead,tfoot,colgroup,'.
|
||||
'col[width|span],'.
|
||||
'blockquote[class|cite|dir],'.
|
||||
'tr[class|style|align|bgcolor|align|valign],'.
|
||||
'td[class|colspan|rowspan|width|style|align|bgcolor|align|valign|nowrap],'.
|
||||
'th[class|colspan|rowspan|width|style|align|bgcolor|align|valign|nowrap],'.
|
||||
'a[href|target|name|title],'.
|
||||
'img[src|alt|title]');
|
||||
$config->set('Attr.DefaultInvalidImage', 'Image removed by htmlpurify');
|
||||
$config->set('Cache.SerializerPath', ($GLOBALS['egw_info']['server']['temp_dir']?$GLOBALS['egw_info']['server']['temp_dir']:sys_get_temp_dir()));
|
||||
$config->set('AutoFormat.Linkify',true);
|
||||
return self::purify($result,$config);
|
||||
}
|
||||
|
||||
/**
|
||||
* deactivates URLs in a text, URLs get replaced by html-links using htmlpurify
|
||||
*
|
||||
* @param string $content text containing URLs
|
||||
* @return string html with activated links
|
||||
*/
|
||||
static function deactivateLinks($_html)
|
||||
{
|
||||
$config = self::purifyCreateDefaultConfig();
|
||||
$config->set('Core.Encoding', (self::$charset?self::$charset:'UTF-8'));
|
||||
// maybe the two following lines are useful for caching???
|
||||
$config->set('HTML.DefinitionID', 'deactivatelinks');
|
||||
$config->set('HTML.DefinitionRev', 1);
|
||||
// doctype and tidylevel
|
||||
$config->set('HTML.Doctype', 'XHTML 1.0 Transitional');
|
||||
$config->set('HTML.TidyLevel', 'light');
|
||||
// EnableID is needed for anchor tags
|
||||
$config->set('Attr.EnableID',true);
|
||||
// actual allowed tags and attributes
|
||||
$config->set('URI.AllowedSchemes', array('http'=>true, 'https'=>true, 'ftp'=>true, 'file'=>true, 'cid'=>true));
|
||||
$config->set('AutoFormat.RemoveEmpty', true);
|
||||
$config->set('HTML.Allowed', 'br,p[align],b,i,u,s,em,pre,tt,strong,strike,center,div[align],hr[class|style],'.
|
||||
'font[size|color],'.
|
||||
'ul[type],ol[type|start],li,'.
|
||||
'h1,h2,h3,'.
|
||||
'span[class|style],'.
|
||||
'table[class|border|cellpadding|cellspacing|width|style|align|bgcolor|align],'.
|
||||
'tbody,thead,tfoot,colgroup,'.
|
||||
'col[width|span],'.
|
||||
'blockquote[class|cite|dir],'.
|
||||
'tr[class|style|align|bgcolor|align|valign],'.
|
||||
'td[class|colspan|rowspan|width|style|align|bgcolor|align|valign|nowrap],'.
|
||||
'th[class|colspan|rowspan|width|style|align|bgcolor|align|valign|nowrap],'.
|
||||
'a[href|target|name|title],'.
|
||||
'img[src|alt|title]');
|
||||
$config->set('Attr.DefaultInvalidImage', 'Image removed by htmlpurify');
|
||||
$config->set('Cache.SerializerPath', ($GLOBALS['egw_info']['server']['temp_dir']?$GLOBALS['egw_info']['server']['temp_dir']:sys_get_temp_dir()));
|
||||
|
||||
$config->set('AutoFormat.DisplayLinkURI',true);
|
||||
$_html = self::purify($_html,$config);
|
||||
return $_html;
|
||||
}
|
||||
|
||||
/**
|
||||
* escapes chars with special meaning in html as entities
|
||||
*
|
||||
@ -221,6 +317,18 @@ class html
|
||||
{
|
||||
$options .= ' size="'.abs($multiple).'"';
|
||||
}
|
||||
// fix width for MSIE in/for selectboxes
|
||||
if (self::$user_agent == 'msie')
|
||||
{
|
||||
if (stripos($options,'onfocus="') === false)
|
||||
{
|
||||
$options .= ' onfocus="window.dropdown_menu_hack(this);" ';
|
||||
}
|
||||
else
|
||||
{
|
||||
$options = str_ireplace('onfocus="','onfocus="window.dropdown_menu_hack(this);',$options);
|
||||
}
|
||||
}
|
||||
$out = "<select name=\"$name\" $options>\n";
|
||||
|
||||
if (!is_array($key))
|
||||
@ -552,11 +660,12 @@ class html
|
||||
* @param string $_name name and id of the input-field
|
||||
* @param string $_mode display mode of the tinymce editor can be: simple, extended or advanced
|
||||
* @param string $_content='' of the tinymce (will be run through htmlspecialchars !!!), default ''
|
||||
* @param string $style='' initial css for the style attribute
|
||||
* @param string $base_href=''
|
||||
* @param string $_height='400px'
|
||||
* @param string $_width='100%'
|
||||
* @param boolean $_purify=true
|
||||
* @return string the necessary html for the textarea
|
||||
*/
|
||||
static function fckEditorQuick($_name, $_mode, $_content='', $_height='400px', $_width='100%')
|
||||
static function fckEditorQuick($_name, $_mode, $_content='', $_height='400px', $_width='100%',$_purify=true)
|
||||
{
|
||||
if (!self::htmlarea_availible() || $_mode == 'ascii')
|
||||
{
|
||||
@ -564,7 +673,7 @@ class html
|
||||
}
|
||||
else
|
||||
{
|
||||
return self::fckEditor($_name, $_content, $_mode, array(), $_height, $_width);
|
||||
return self::fckEditor($_name, $_content, $_mode, array(), $_height, $_width,'',$_purify);
|
||||
}
|
||||
}
|
||||
|
||||
@ -726,11 +835,24 @@ class html
|
||||
return self::form(self::submit_button($name,$label),$hidden_vars,$url,$url_vars,$form_name,'',$method);
|
||||
}
|
||||
|
||||
const THEAD = 1;
|
||||
const TFOOT = 2;
|
||||
const TBODY = 3;
|
||||
static $part2tag = array(
|
||||
self::THEAD => 'thead',
|
||||
self::TFOOT => 'tfoot',
|
||||
self::TBODY => 'tbody',
|
||||
);
|
||||
|
||||
/**
|
||||
* creates table from array of rows
|
||||
*
|
||||
* abstracts the html stuff for the table creation
|
||||
* Example: $rows = array (
|
||||
* 'h1' => array( // optional header row(s)
|
||||
* ),
|
||||
* 'f1' => array( // optional footer row(s)
|
||||
* ),
|
||||
* '1' => array(
|
||||
* 1 => 'cell1', '.1' => 'colspan=3',
|
||||
* 2 => 'cell2',
|
||||
@ -747,12 +869,20 @@ class html
|
||||
{
|
||||
$html = $no_table_tr ? '' : "<table $options>\n";
|
||||
|
||||
$part = 0;
|
||||
foreach($rows as $key => $row)
|
||||
{
|
||||
if (!is_array($row))
|
||||
{
|
||||
continue; // parameter
|
||||
}
|
||||
// get the current part from the optional 'h' or 'f' prefix of the key
|
||||
$p = $key[0] == 'h' ? html::THEAD : ($key[0] == 'f' ? html::TFOOT : html::TBODY);
|
||||
if ($part < $p && ($part || $p < self::TBODY)) // add only allowed and neccessary transitions
|
||||
{
|
||||
if ($part) $html .= '</'.self::$part2tag[$part].">\n";
|
||||
$html .= '<'.self::$part2tag[$part=$p].">\n";
|
||||
}
|
||||
$html .= $no_table_tr && $key == 1 ? '' : "\t<tr ".$rows['.'.$key].">\n";
|
||||
|
||||
foreach($row as $key => $cell)
|
||||
@ -778,6 +908,10 @@ class html
|
||||
{
|
||||
echo "<p>".function_backtrace()."</p>\n";
|
||||
}
|
||||
if ($part) // close current part
|
||||
{
|
||||
$html .= "</".self::$part2tag[$part].">\n";
|
||||
}
|
||||
$html .= "</table>\n";
|
||||
|
||||
if ($no_table_tr)
|
||||
@ -849,16 +983,17 @@ class html
|
||||
*/
|
||||
static function image( $app,$name,$title='',$options='' )
|
||||
{
|
||||
if (substr($name,0,5) == 'vfs:/') // vfs pseudo protocoll
|
||||
{
|
||||
$name = egw::link(egw_vfs::download_url(substr($name,4)));
|
||||
}
|
||||
if (is_array($name)) // menuaction and other get-vars
|
||||
{
|
||||
$name = $GLOBALS['egw']->link('/index.php',$name);
|
||||
}
|
||||
if ($name[0] == '/' || substr($name,0,7) == 'http://' || substr($name,0,8) == 'https://')
|
||||
if (substr($name,0,5) == 'vfs:/') // vfs pseudo protocoll
|
||||
{
|
||||
$name = egw::link(egw_vfs::download_url(substr($name,4)));
|
||||
}
|
||||
if ($name[0] == '/' || substr($name,0,7) == 'http://' || substr($name,0,8) == 'https://' || stripos($name,'etemplate/thumbnail.php') )
|
||||
{
|
||||
if (!($name[0] == '/' || substr($name,0,7) == 'http://' || substr($name,0,8) == 'https://')) $name = '/'.$name;
|
||||
$url = $name;
|
||||
}
|
||||
else // no URL, so try searching the image
|
||||
@ -880,7 +1015,7 @@ class html
|
||||
$path = EGW_SERVER_ROOT.$url;
|
||||
}
|
||||
|
||||
if (is_null($path) || !@is_readable($path))
|
||||
if (is_null($path) || (!@is_readable($path) && stripos($path,'webdav.php')===false))
|
||||
{
|
||||
// if the image-name is a percentage, use a progressbar
|
||||
if (substr($name,-1) == '%' && is_numeric($percent = substr($name,0,-1)))
|
||||
@ -1212,6 +1347,24 @@ class html
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* creates the HTMLPurifier default config
|
||||
*
|
||||
* @return HTMLPurifier_Config object
|
||||
*/
|
||||
static function purifyCreateDefaultConfig()
|
||||
{
|
||||
// add htmlpurifiers library to include_path
|
||||
require_once(EGW_API_INC.'/htmlpurifier/library/HTMLPurifier.path.php');
|
||||
// include most of the required files, for best performance with bytecode caches
|
||||
require_once(EGW_API_INC.'/htmlpurifier/library/HTMLPurifier.includes.php');
|
||||
// installs an autoloader for other files
|
||||
require_once(EGW_API_INC.'/htmlpurifier/library/HTMLPurifier.autoload.php');
|
||||
// testcase to test the processing of purify
|
||||
//$html = "<h1 onclick=\"alert('hallo');\"> h1 </h1>".$html;
|
||||
return HTMLPurifier_Config::createDefault();
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs HTMLPurifier over supplied html to remove malicious code
|
||||
*
|
||||
@ -1232,11 +1385,12 @@ class html
|
||||
require_once(EGW_API_INC.'/htmlpurifier/library/HTMLPurifier.includes.php');
|
||||
// installs an autoloader for other files
|
||||
require_once(EGW_API_INC.'/htmlpurifier/library/HTMLPurifier.autoload.php');
|
||||
|
||||
// testcase to test the processing of purify
|
||||
//$html = "<h1 onclick=\"alert('hallo');\"> h1 </h1>".$html;
|
||||
if (is_null($config))
|
||||
{
|
||||
$config = HTMLPurifier_Config::createDefault();
|
||||
$config->set('Core.Encoding', self::$charset);
|
||||
$config->set('Core.Encoding', (self::$charset?self::$charset:'UTF-8'));
|
||||
// maybe the two following lines are useful for caching???
|
||||
$config->set('HTML.DefinitionID', 'egroupware');
|
||||
$config->set('HTML.DefinitionRev', 1);
|
||||
@ -1258,15 +1412,63 @@ class html
|
||||
'td[class|colspan|rowspan|width|style|align|bgcolor|align|valign|nowrap],'.
|
||||
'th[class|colspan|rowspan|width|style|align|bgcolor|align|valign|nowrap],'.
|
||||
'a[href|target|name|title],img[src|alt|title]');
|
||||
$config->set('Cache.SerializerPath', $GLOBALS['egw_info']['server']['temp_dir']);
|
||||
$config->set('Cache.SerializerPath', ($GLOBALS['egw_info']['server']['temp_dir']?$GLOBALS['egw_info']['server']['temp_dir']:sys_get_temp_dir()));
|
||||
}
|
||||
$purifier = new HTMLPurifier($config);
|
||||
// the latter may enable you to modify the config later on, but by now
|
||||
// the effort for e.g. enabling anchor tags is already included above
|
||||
//$def =& $purifier->config->getHTMLDefinition(true);
|
||||
//$def->addAttribute('a', 'name', 'Text');
|
||||
|
||||
|
||||
}
|
||||
return $purifier->purify( $html );
|
||||
}
|
||||
|
||||
/**
|
||||
* Output content headers for file downloads
|
||||
*
|
||||
* @author Miles Lott originally in browser class
|
||||
* @param string $fn filename
|
||||
* @param string $mime='' mimetype or '' (default) to detect it from filename, using mime_magic::filename2mime()
|
||||
* @param int $length=0 content length, default 0 = skip that header
|
||||
* @param boolean $nocache=true send headers to disallow browser/proxies to cache the download
|
||||
*/
|
||||
public static function content_header($fn,$mime='',$length=0,$nocache=True)
|
||||
{
|
||||
// if no mime-type is given or it's the default binary-type, guess it from the extension
|
||||
if(empty($mime) || $mime == 'application/octet-stream')
|
||||
{
|
||||
$mime = mime_magic::filename2mime($fn);
|
||||
}
|
||||
if($fn)
|
||||
{
|
||||
if(self::$user_agent == 'msie') // && self::$ua_version == '5.5')
|
||||
{
|
||||
$attachment = '';
|
||||
}
|
||||
else
|
||||
{
|
||||
$attachment = ' attachment;';
|
||||
}
|
||||
|
||||
// Show this for all
|
||||
header('Content-disposition:'.$attachment.' filename="'.$fn.'"');
|
||||
header('Content-type: '.$mime);
|
||||
|
||||
if($length)
|
||||
{
|
||||
header('Content-length: '.$length);
|
||||
}
|
||||
|
||||
if($nocache)
|
||||
{
|
||||
header('Pragma: no-cache');
|
||||
header('Pragma: public');
|
||||
header('Expires: 0');
|
||||
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
html::_init_static();
|
||||
|
Loading…
Reference in New Issue
Block a user