We violate this for a users profile css, because thats its reason for existing. */ if ($template == 'css_profile.css') { $userId = 0; if (isset($_REQUEST['userid']) and intval($_REQUEST['userid']) and isset($_REQUEST['showusercss']) and intval($_REQUEST['showusercss']) == 1) { $userId = intval($_REQUEST['userid']); } $templater->register('userid', $userId); } $template = $templater->render(true, false, true); if ($count > 0) { $template = preg_replace("#@charset .*#i", "", $template); } $count++; $output .= $template; } $output = vB_String::getCssMinifiedText($output); if ($output == '') { // this can happen if an invalid css template name is passed header('Content-Type: text/css'); echo '/* Unable to find css template */'; exit; } if (!headers_sent() and vB::getDatastore()->getOption('gzipoutput')) { $output = fetch_gzipped_text($output, vB::getDatastore()->getOption('gziplevel')); } header('Content-Type: text/css'); header('Cache-control: max-age=31536000, private'); header('Expires: ' . gmdate("D, d M Y H:i:s", TIMENOW + 31536000) . ' GMT'); header('Pragma:'); header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $style['dateline']) . ' GMT'); header('Content-Length: ' . strlen($output));
/** * Writes style css directory on disk * * @param int $styleid * @param string $parentlist -- csv list of ancestors for this style * @param string $dir -- the "direction" of the css to write. Either 'ltr' or 'rtl' (there are actually two directories per style) */ function write_style_css_directory($styleid, $parentlist, $dir = 'ltr') { //verify that we have or can create a style directory $styledir = DIR . vB_Api::instanceInternal('style')->fetchCssLocation() . '/style' . str_pad($styleid, 5, '0', STR_PAD_LEFT) . ($dir == 'ltr' ? 'l' : 'r'); //if we have a file that's not a directory or not writable something is wrong. if (file_exists($styledir) and (!is_dir($styledir) or !is_writable($styledir))) { return false; } //clear any old files. if (file_exists($styledir)) { delete_style_css_directory($styleid, $dir, true); } //create the directory -- if it still exists try to continue with the existing dir if (!file_exists($styledir)) { if (!@mkdir($styledir)) { return false; } } //check for success. if (!is_dir($styledir) or !is_writable($styledir)) { return false; } //write out the files for this style. $parentlistarr = explode(',', $parentlist); $set = vB::getDbAssertor()->assertQuery('vBForum:fetchParentTemplates', array('parentlist' => $parentlistarr)); //collapse the list. $css_templates = array(); foreach ($set as $row) { $css_templates[] = $row['title']; } $stylelib = vB_Library::instance('Style'); $stylelib->switchCssStyle($styleid, $css_templates); if ($dir == 'ltr') { vB_Template_Runtime::addStyleVar('left', 'left'); vB_Template_Runtime::addStyleVar('right', 'right'); vB_Template_Runtime::addStyleVar('textdirection', 'ltr'); } else { vB_Template_Runtime::addStyleVar('left', 'right'); vB_Template_Runtime::addStyleVar('right', 'left'); vB_Template_Runtime::addStyleVar('textdirection', 'rtl'); } // Get new css cache bust $stylelib->setCssFileDate($styleid); $cssfiledate = $stylelib->getCssFileDate($styleid); $base = get_base_url_for_css(); if ($base === false) { return false; } $templates = array(); foreach ($css_templates as $title) { //I'd call this a hack but there probably isn't a cleaner way to do this. //The css is published to a different directory than the css.php file //which means that relative urls that works for css.php won't work for the //published directory. Unfortunately urls from the webroot don't work //because the forum often isn't located at the webroot and we can only //specify urls from the forum root. And css doens't provide any way //of setting a base url like html does. So we are left to "fixing" //any relative urls in the published css. // //We leave alone any urls starting with '/', 'http', and 'https:' //there are other valid urls, but nothing that people should be //using in our css files. $text = vB_Template::create($title)->render(true); //update image urls to be fully qualified. $re = '#url\\(\\s*["\']?(?!/|http:|https:|"/|\'/)#'; $text = preg_replace($re, "\$0{$base}", $text); $text = vB_String::getCssMinifiedText($text); $templates[$title] = $text; if (!write_css_file("{$styledir}/{$cssfiledate}-{$title}", $text)) { return false; } } static $vbdefaultcss = array(), $cssfiles = array(); if (empty($vbdefaultcss)) { require_once DIR . '/includes/class_xml.php'; $cssfilelist = vB_Api_Product::loadProductXmlList('cssrollup', true); if (empty($cssfilelist['vbulletin'])) { $vbphrase = vB_Api::instanceInternal('phrase')->fetch(array('could_not_open_x')); echo construct_phrase($vbphrase['could_not_open_x'], DIR . '/includes/xml/cssrollup_vbulletin.xml'); exit; } else { $mainfile = array_shift($cssfilelist); } $xmlobj = new vB_XML_Parser(false, $mainfile); $data = $xmlobj->parse(); if (!is_array($data['rollup'][0])) { $data['rollup'] = array($data['rollup']); } foreach ($data['rollup'] as $file) { foreach ($file['template'] as $name) { $vbdefaultcss["{$file['name']}"] = $file['template']; } } foreach ($cssfilelist as $css_file => $file) { $xmlobj = new vB_XML_Parser(false, $file); $data = $xmlobj->parse(); $products = vB::getDatastore()->getValue('products'); if ($data['product'] and empty($products["{$data['product']}"])) { // attached to a specific product and that product isn't enabled continue; } if (!is_array($data['rollup'][0])) { $data['rollup'] = array($data['rollup']); } $cssfiles[$css_file]['css'] = $data['rollup']; } } foreach ($cssfiles as $css_file => $files) { if (is_array($files['css'])) { foreach ($files['css'] as $file) { if (process_css_rollup_file($file['name'], $file['template'], $templates, $styleid, $styledir, $vbdefaultcss) === false) { return false; } } } } foreach ($vbdefaultcss as $xmlfile => $files) { if (process_css_rollup_file($xmlfile, $files, $templates, $styleid, $styledir) === false) { return false; } } return true; }