function _DownloadFile($filename = "", $cacheSeconds = 1800, $contentType = "application/zip") { global $AR; $context = pobject::getContext(); $me = $context['arCurrentObject']; $size = filesize($this->_filename); ldSetContent($contentType, $size); $expires = time() + $cacheSeconds; if ($AR->user->data->login == "public" || $me->CheckPublic("read")) { ldSetClientCache(true, $expires); } if ($filename) { ldHeader("Content-Disposition: attachment; filename={$filename}"); ldHeader("Content-length:" . (string) $size); } readfile($this->_filename); }
function ldProcessRequest($AR_PATH_INFO = null) { global $AR; global $ARCurrent; global $store_config; global $auth_config; global $cache_config; global $store; global $context; global $DB; global $path; global $function; global $nls; $writecache = false; // go check for a sessionid $root = $AR->root; $session_id = 0; $re = "^/-(.{4})-/"; $originalPathInfo = $AR_PATH_INFO; // Store this to pass to the refresh cache on shutdown function; if (preg_match('|' . $re . '|', $AR_PATH_INFO, $matches)) { $session_id = $matches[1]; $AR_PATH_INFO = substr($AR_PATH_INFO, strlen($matches[0]) - 1); $AR->hideSessionIDfromURL = false; } elseif ($AR->hideSessionIDfromURL) { $cookies = (array) ldGetCredentials(); $current = ldGetCookieSession(); if (array_key_exists($current, $cookies)) { $session_id = $current; } } // set the default user (public) $AR->login = "******"; // look for the template $split = strrpos($AR_PATH_INFO, "/"); $path = substr($AR_PATH_INFO, 0, $split + 1); $function = substr($AR_PATH_INFO, $split + 1); if (!$function) { if (!isset($arDefaultFunction) || $arDefaultFunction == '') { $arDefaultFunction = "view.html"; } $function = $arDefaultFunction; if (isset($arFunctionPrefix) && $arFunctionPrefix != '') { $function = $arFunctionPrefix . $function; } $AR_PATH_INFO .= $function; } // yes, the extra '=' is needed, don't remove it. trust me. $ldCacheFilename = strtolower($AR_PATH_INFO) . "="; // for the new multiple domains per site option (per language), we need this // since the nls isn't literaly in the url anymore. $ldCacheFilename .= str_replace(':', '=', str_replace('/', '', $AR->host)) . '='; $qs = ldGetServerVar("QUERY_STRING"); if ($qs != '') { $ldCacheFilename .= sha1($qs); } if ($session_id) { $cachedimage = $store_config["files"] . "cache/session" . $ldCacheFilename; $cachedheader = $store_config["files"] . "cacheheaders/session" . $ldCacheFilename; } else { $cachedimage = $store_config["files"] . "cache/normal" . $ldCacheFilename; $cachedheader = $store_config["files"] . "cacheheaders/normal" . $ldCacheFilename; } if ($AR->ESI) { ob_start(); } $timecheck = time(); if (file_exists($cachedimage)) { $staleTotalTime = filemtime($cachedimage) - filectime($cachedimage); $staleCurrent = $timecheck - filectime($cachedimage); if ($staleTotalTime != 0) { $stalePercentage = sprintf("%.2f", 100 * $staleCurrent / $staleTotalTime); } else { $stalePercentage = 100; } if ($stalePercentage < 0) { $stalePercentage = 0; } else { if ($stalePercentage > 100) { $stalePercentage = 100; } } if (!headers_sent()) { header("X-Ariadne-Cache-Stale: {$stalePercentage}%"); } } // add min-fresh if the client asked for it if (isset($ARCurrent->RequestCacheControl["min-fresh"])) { $timecheck += $ARCurrent->RequestCacheControl["min-fresh"]; } if (file_exists($cachedimage) && (($mtime = @filemtime($cachedimage)) > $timecheck || $mtime == 0) && $_SERVER["REQUEST_METHOD"] != "POST" && $ARCurrent->RequestCacheControl["no-cache"] != true && $ARCurrent->refreshCacheOnShutdown !== true) { $ctime = filemtime($cachedimage); // FIXME: Waarom moet dit mtime zijn? Zonder mtime werkt de if-modified-since niet; if (rand(20, 80) < $stalePercentage) { header("X-Ariadne-Cache-Refresh: refreshing on shutdown"); register_shutdown_function("ldCacheRequest", $originalPathInfo); // Rerun the request with the original path info; } else { header("X-Ariadne-Cache-Refresh: skipped, still fresh enough"); } if (!$AR->ESI && $_SERVER['HTTP_IF_MODIFIED_SINCE'] && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= $ctime) { // the mtime is used as expiration time, the ctime is the correct last modification time. // as an object clears the cache upon a save. // Send the original headers - they will already contain the correct max-age and expires values; if (file_exists($cachedheader)) { $filedata = file($cachedheader); if (is_array($filedata)) { while (list($key, $header) = each($filedata)) { ldHeader($header); } } } header("X-Ariadne-Cache: Hit"); ldHeader("HTTP/1.1 304 Not Modified"); } else { if (file_exists($cachedheader)) { // Cache header file also contains information about Cache-control; $filedata = file($cachedheader); if (is_array($filedata)) { while (list($key, $header) = each($filedata)) { ldHeader($header); } } } header("X-Ariadne-Cache: Hit"); // Send this after the cached headers to overwrite the cached cache-miss header; if ($AR->ESI) { if (false && $_SERVER['HTTP_IF_MODIFIED_SINCE'] && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= $ctime) { ldHeader("HTTP/1.1 304 Not modified"); } else { $data = file_get_contents($cachedimage); include_once $store_config['code'] . "modules/mod_esi.php"; // Replace the session IDs before the ESI process call to pass the correct session ID information... if ($session_id && !$AR->hideSessionIDfromURL) { $tag = '{arSessionID}'; $data = str_replace($tag, "-{$session_id}-", $data); } $data = ESI::esiProcess($data); // ... and then replace the session IDs that were generated in de ESI case; $tag = '{arSessionID}'; if ($session_id && !$AR->hideSessionIDfromURL) { $data = str_replace($tag, "-{$session_id}-", $data); } else { if ($session_id && $AR->hideSessionIDfromURL) { $data = str_replace($tag, '', $data); } } $data_len = strlen($data); header("Content-Length: " . $data_len); echo $data; } } else { if ($session_id) { $tag = '{arSessionID}'; $data = file_get_contents($cachedimage); $tag = '{arSessionID}'; if (!$AR->hideSessionIDfromURL) { $data = str_replace($tag, "-{$session_id}-", $data); } else { $data = str_replace($tag, '', $data); } $data_len = strlen($data); header("Content-Length: " . $data_len); echo $data; } else { $data_len = filesize($cachedimage); header("Content-Length: " . $data_len); readfile($cachedimage); } } } $writecache = false; // Prevent recaching cached image; } else { if (!headers_sent()) { header("X-Ariadne-Cache: Miss"); } /* start output buffering */ ob_start(); global $ldOutputBufferActive; $ldOutputBufferActive = true; ob_implicit_flush(0); // look for the language $split = strpos(substr($AR_PATH_INFO, 1), "/"); $ARCurrent->nls = substr($path, 1, $split); if (!isset($AR->nls->list[$ARCurrent->nls])) { // not a valid language $ARCurrent->nls = ""; $nls = $AR->nls->default; // but we can find out if the user has any preferences preg_match_all("%([a-zA-Z]{2}|\\*)[a-zA-Z-]*(?:;q=([0-9.]+))?%", $_SERVER["HTTP_ACCEPT_LANGUAGE"], $regs, PREG_SET_ORDER); $ARCurrent->acceptlang = array(); $otherlangs = array(); $otherq = false; foreach ($regs as $reg) { if (!isset($reg[2])) { $reg[2] = 1; } if ($reg[1] == "*") { $otherq = $reg[2]; } else { if ($AR->nls->list[$reg[1]]) { $otherlangs[] = $reg[1]; $ARCurrent->acceptlang[$reg[1]] = $reg[2]; } } } if ($otherq !== false) { $otherlangs = array_diff(array_keys($AR->nls->list), $otherlangs); foreach ($otherlangs as $lang) { $ARCurrent->acceptlang[$lang] = $otherq; } } arsort($ARCurrent->acceptlang); } else { // valid language $path = substr($path, $split + 1); // ldSetNls($ARCurrent->nls); $nls = $ARCurrent->nls; } $args = array_merge($_GET, $_POST); // instantiate the store $inst_store = $store_config["dbms"] . "store"; $store = new $inst_store($root, $store_config); //$store->rootoptions = $rootoptions; if ($session_id) { ldStartSession($session_id); } // instantiate the ARnls if ($ARCurrent->nls != "") { ldSetNls($nls); } if (substr($function, -6) == ".phtml") { // system template: no language check $ARCurrent->nolangcheck = 1; } $ext = pathinfo($function, PATHINFO_EXTENSION); switch ($ext) { case 'css': ldSetContent('text/css; charset=utf-8'); break; case 'js': ldSetContent('application/javascript; charset=utf-8'); break; case 'json': ldSetContent('application/json; charset=utf-8'); break; case 'xml': ldSetContent('text/xml; charset=utf-8'); break; case 'jpg': ldSetContent('image/jpeg'); break; case 'gif': ldSetContent('image/gif'); break; case 'png': ldSetContent('image/png'); break; case 'svg': ldSetContent('image/svg+xml'); break; default: ldSetContent('text/html; charset=utf-8'); break; } $ARCurrent->arContentTypeSent = true; register_shutdown_function("ldOnFinish"); $auth_class = "mod_auth_" . $auth_config["method"]; $mod_auth = new $auth_class($auth_config); $username = isset($args["ARLogin"]) ? $args["ARLogin"] : null; $password = isset($args["ARPassword"]) ? $args["ARPassword"] : null; $result = $mod_auth->checkLogin($username, $password, $path); if ($result !== true) { if ($result == LD_ERR_ACCESS) { ldAccessDenied($path, $ARnls["accessdenied"], $args, $function); $function = false; } else { if ($result == LD_ERR_SESSION && !$AR->hideSessionIDfromURL) { ldAccessTimeout($path, $ARnls["sessiontimeout"], $args, $function); $function = false; } else { if ($result == LD_ERR_EXPIRED) { ldAccessPasswordExpired($path, $ARnls["sessionpasswordexpired"], $args, $function); $function = false; } } } } // valid new login, without a session, morph to login.redirect.php to redirect to a session containing url if (!$session_id && $args["ARLogin"] && $args["ARPassword"] && $function !== false && !$AR->hideSessionIDfromURL) { if (!$ARCurrent->session->get("oldArCallArgs", 1)) { $ARCurrent->session->put("oldGET", $_GET, 1); $ARCurrent->session->put("oldPOST", $_POST, 1); $ARCurrent->session->put("oldArCallArgs", $args, 1); $ARCurrent->session->save(0, true); } if ($arDefaultFunction !== $function) { $args["arRequestedTemplate"] = $function; } else { $args["arRequestedTemplate"] = ""; } $function = "login.redirect.php"; } else { if ($session_id) { if ($ARCurrent->session->get("ARSessionTimedout", 1)) { if (!$ARCurrent->session->get("oldArCallArgs", 1)) { $ARCurrent->session->put("oldGET", $_GET, 1); $ARCurrent->session->put("oldPOST", $_POST, 1); $ARCurrent->session->put("oldArCallArgs", $args, 1); $ARCurrent->session->save(0, true); } } else { if ($ARCurrent->session->get("oldArCallArgs", 1)) { $_GET = array_merge($_GET, (array) $ARCurrent->session->get("oldGET", 1)); $_POST = array_merge($_POST, (array) $ARCurrent->session->get("oldPOST", 1)); $args = $ARCurrent->session->get("oldArCallArgs", 1); $args = array_merge($_GET, $_POST, $args); // $args, $_GET, $_POST ); $ARCurrent->session->put("oldArCallArgs", "", 1); $ARCurrent->session->put("oldGET", "", 1); $ARCurrent->session->put("oldPOST", "", 1); } } } } $xss_vars = array(); ldGatherXSSInput($xss_vars, $_GET); ldGatherXSSInput($xss_vars, $_POST); $filenames = array_map(function ($e) { return $e['name']; }, $_FILES); ldGatherXSSInput($xss_vars, $filenames); ldGatherXSSInput($xss_vars, $function); ldGatherXSSInput($xss_vars, $path); global $ldXSSProtectionActive; if (count($xss_vars)) { $ldXSSProtectionActive = true; } if ($function !== false) { // finally call the requested object unset($store->total); if (ldCheckAllowedTemplate($function)) { $store->call($function, $args, $store->get($path)); $writecache = true; } if (!$store->total) { ldObjectNotFound($path, $function, $args); } } if (count($xss_vars)) { $image = ob_get_contents(); ob_clean(); $header = $ARCurrent->ldHeaders["content-type"]; $xssDetected = false; preg_match('/^content-type:\\s+([^ ;]+)/i', $header, $matches); $mimetype = strtolower($matches[1]); if (substr($mimetype, 0, 5) == 'text/') { krsort($xss_vars, SORT_NUMERIC); foreach ($xss_vars as $values) { if (is_array($values)) { foreach ($values as $value) { $occurances = substr_count($image, $value); if ($occurances > 0) { $xssDetected = true; break 2; } } } } } if ($xssDetected) { $newargs = array(); $newargs["arRequestedArgs"] = $args; $newargs["arRequestedTemplate"] = $function; $newargs["arSuspectedArgs"] = $xss_vars; $newargs["arResultOutput"] = $image; $store->call('user.xss.html', $newargs, $store->get($path)); } else { echo $image; } } } // now check for outputbuffering (caching) if ($image = ob_get_contents()) { // Calculate browser side cache settings based on settings collected in the call chain; // // Rules: do not cache wins. short cache time wins over longer cache time. Unset values don't get to play. // // Overlord rule: if the request method was not a get, or debugging was used, do not cache. Ever. // // If pinp says arDontCache, then do not cache; // // If ESI was used and hit a cached image, use the cache settings from the cache image; if ($_SERVER['REQUEST_METHOD'] != 'GET' || $DB["wasUsed"] > 0) { // Do not cache on client. ldSetBrowserCache(false); } else { if (is_array($ARCurrent->cache) && ($file = array_pop($ARCurrent->cache))) { // This will generate an error, do not cache on client; ldSetBrowserCache(false); } else { if ($ARCurrent->arDontCache) { // PINP told us not to cache; ldSetBrowserCache(false); } else { if (!$writecache) { // Image came from the cache, it already has browser cache headers; } else { // Defaults for browser caching; // Calls without session: public, max-age 1800; // Calls with session without call chain (disk templates): private, no-cache no-store must-revalidate max-age=0 // Calls with session with call chain (pinp templates): private, max-age=1800; // FIXME: Make the calls with session less trigger happy on not caching; /* if ($session_id && sizeof($ARCurrent->cacheCallChainSettings)) { // With session and pinp templates; $browserCachePrivate = true; $browserCacheMaxAge = 1800; $browserCacheNoStore = false; $browserCacheNoCache = false; $browserCacheMustRevalidate = false; } else */ if ($session_id) { // With session, disk templates only $browserCachePrivate = true; $browserCacheMaxAge = 0; $browserCacheNoStore = true; $browserCacheNoCache = true; $browserCacheMustRevalidate = true; } else { // Without session and all other corner cases; $browserCachePrivate = false; $defaultMaxAge = 1800; $browserCacheNoStore = false; $browserCacheNoCache = false; $browserCacheMustRevalidate = false; } $browserCachecacheSetting = 0; // Default = inherit; // FIXME: The defaults for with session ID are now to not cache; if (is_array($ARCurrent->cacheCallChainSettings)) { foreach ($ARCurrent->cacheCallChainSettings as $objectId => $pathCacheSetting) { $browserCachePrivate = $browserCachePrivate || $pathCacheSetting['browserCachePrivate']; // If anyone says 'private', make it so. $browserCacheNoStore = $browserCacheNoStore || $pathCacheSetting['browserCacheNoStore']; // If anyone says 'no-store', make it so. $browserCacheNoCache = $browserCacheNoCache || $pathCacheSetting['browserCacheNoCache']; // If anyone says 'no-cache', make it so. $browserCacheMustRevalidate = $browserCacheMustRevalidate || $pathCacheSetting['browserCacheMustRevalidate']; // If anyone says 'must-revalidate', make it so. $browserCacheNoTransform = $browserCacheNoTransform || $pathCacheSetting['browserCacheNoTransform']; // If anyone says 'no-transform', make it so. $browserCacheProxyRevalidate = $browserCacheProxyRevalidate || $pathCacheSetting['browserCacheProxyRevalidate']; // If anyone says 'proxy-revalidate', make it so. if (isset($pathCacheSetting['browserCacheMaxAge']) && is_numeric($pathCacheSetting['browserCacheMaxAge'])) { if (isset($browserCacheMaxAge)) { $browserCacheMaxAge = min($browserCacheMaxAge, $pathCacheSetting['browserCacheMaxAge']); } else { $browserCacheMaxAge = $pathCacheSetting['browserCacheMaxAge']; } } if (isset($pathCacheSetting['browserCacheSMaxAge']) && is_numeric($pathCacheSetting['browserCacheMaxAge'])) { if (isset($browserCacheSMaxAge)) { $browserCacheSMaxAge = min($browserCacheSMaxAge, $pathCacheSetting['browserCacheSMaxAge']); } else { $browserCacheSMaxAge = $pathCacheSetting['browserCacheSMaxAge']; } } } if (!isset($browserCacheMaxAge) && isset($defaultMaxAge)) { $browserCacheMaxAge = $defaultMaxAge; } } ldSetBrowserCache(array("browserCachePrivate" => $browserCachePrivate, "browserCacheNoStore" => $browserCacheNoStore, "browserCacheNoCache" => $browserCacheNoCache, "browserCacheMustRevalidate" => $browserCacheMustRevalidate, "browserCacheNoTransform" => $browserCacheNoTransform, "browserCacheProxyRevalidate" => $browserCacheProxyRevalidate, "browserCacheMaxAge" => $browserCacheMaxAge, "browserCacheSMaxAge" => $browserCacheSMaxAge)); } } } } $image_len = strlen($image); if ($ARCurrent->session && $ARCurrent->session->id) { $ldCacheFilename = "/session" . $ldCacheFilename; $image = str_replace('-' . $ARCurrent->session->id . '-', '{arSessionID}', $image); } else { $ldCacheFilename = "/normal" . $ldCacheFilename; } // because we have the full content, we can now also calculate the content length ldHeader("Content-Length: " . $image_len); // flush the buffer, this will send the contents to the browser ob_end_flush(); debug("loader: ob_end_flush()", "all"); // Calculate server side cache settings based on settings collected in the call chain; // // Rules: do not cache wins. short cache time wins over longer cache time. Unset values don't get to play. // // Overlord rule: if the request method was not a get, or debugging was used, do not cache. Ever. // // If pinp says arDontCache, then do not cache; // // If ESI was used and hit a cached image, do not write the image; if ($_SERVER['REQUEST_METHOD'] != 'GET' || $DB["wasUsed"] > 0) { // Do not cache on server. // header("X-Ariadne-Cache-Skipped: DB Used"); } else { if (is_array($ARCurrent->cache) && ($file = array_pop($ARCurrent->cache))) { error("cached() opened but not closed with savecache()"); // header("X-Ariadne-Cache-Skipped: cached problem."); } else { if ($ARCurrent->arDontCache) { // PINP told us not to cache; // header("X-Ariadne-Cache-Skipped: arDontCache"); } else { if (!$writecache) { // ESI was used and hit a cached image, do not write the image; // header("X-Ariadne-Cache-Skipped: cached image used"); } else { // header("X-Ariadne-Cache-Skipped: Writing cache now"); // Cache setting values: // -2 = Refresh on change; Set the cache time on server to 999 hours (unlimited); // -1 = Do not cache // 0 = Inherit // > 0: Refresh on request. The number is the amount of hours that the cache is 'fresh'. This can be a fraction/float value; $cacheSetting = 0; // Default = inherit; $serverCachePrivate = 0; // do not allow caching of sessions if (is_array($ARCurrent->cacheCallChainSettings)) { foreach ($ARCurrent->cacheCallChainSettings as $objectId => $pathCacheSetting) { // FIXME: also 'resolve' $serverCachePrivate $serverCache = $pathCacheSetting['serverCache']; if ($serverCache == 0 || !isset($serverCache)) { // This path does not want to play; $serverCache = $pathCacheSetting['serverCacheDefault']; } if ($serverCache == -2) { // Sorry, we meant that the cache image should be valid forever; $serverCache = 999; } if ($cacheSetting == 0) { $cacheSetting = $serverCache; } else { $cacheSetting = min($serverCache, $cacheSetting); } if ($cacheSetting == -1) { // If someone told us to not cache, skip checking because nothing anyone else tells us will change this fact. break; } } } // header("X-Ariadne-Cache-Setting: $cacheSetting"); if ($ARCurrent->session->id && $cacheSetting > 0) { // we have a session id, can we cache ? // FIXME: add support for $serverCachePrivate in the config and cache dialog if (!($serverCachePrivate === 1 || $ARCurrent->arDoCachePrivate != false)) { $cacheSetting = -1; } } if ($cacheSetting > 0) { // If we are allowed to cache, write the image now. if ($store) { // Sanity check to only write cache images if a store was initialized; // FIXME: cacheCallChainSettings contains the objects that were called for this cache image; // FIXME: cacheTemplateChain containers the templates that were called for this cache image; ldSetCache($ldCacheFilename, $cacheSetting, $image, @implode("\n", $ARCurrent->ldHeaders)); $cachestore = new cache($cache_config); $cachestore->save($ldCacheFilename, $ARCurrent->cacheCallChainSettings, $ARCurrent->cacheTemplateChain); } } } } } } } if ($AR->ESI > 0) { // Prevent ESI from looping when the ESI result has ESI tags in them. // Reducing the AR->ESI number by 1 gives the flexibility to allow 2 or 3 ESI loops if desired. // Setting it to false would mean you only get 1 ESI loop, which might not be the desired effect. $AR->ESI = (int) $AR->ESI; $AR->ESI--; $image = ob_get_contents(); ob_end_clean(); include_once $store_config['code'] . "modules/mod_esi.php"; $image = ESI::esiProcess($image); $image_len = strlen($image); if ($ARCurrent->arDontCache) { // FIXME: ook de cachetime 'niet cachen' uit het cachedialoog werkend maken... || $ARCurrent->cachetime == 0) { ldSetBrowserCache(false); } ldHeader("Content-Length: " . $image_len); echo $image; } }
function generate($config) { global $fpdf_charwidths; global $g_baseurl; global $g_border; global $g_box_uid; global $g_boxes; global $g_colors; global $g_config; global $g_css; global $g_css_defaults_obj; global $g_css_handlers; global $g_css_index; global $g_css_obj; global $g_font_family; global $g_font_resolver; global $g_font_resolver_pdf; global $g_font_size; global $g_frame_level; global $g_html_entities; global $g_image_cache; global $g_last_assigned_font_id; global $g_list_item_nums; global $g_manager_encodings; global $g_media; global $g_predefined_media; global $g_pt_scale; global $g_px_scale; global $g_stylesheet_title; global $g_table_border; global $g_tag_attrs; global $g_unicode_glyphs; global $g_utf8_converters; global $g_utf8_to_encodings_mapping_pdf; global $g_valign; global $psdata; global $g_font_style; global $g_font_family; global $g_font_weight; global $g_font_size; global $g_line_height; // global $base_font_size; $context = pobject::getContext(); $me = $context["arCurrentObject"]; require_once HTML2PS_LOCATION . 'pipeline.factory.class.php'; set_time_limit(600); check_requirements(); $g_baseurl = trim($config['URL']); if ($g_baseurl === "") { $me->error = "Please specify URL to process!"; return false; } // Add HTTP protocol if none specified if (!preg_match("/^https?:/", $g_baseurl)) { $g_baseurl = 'http://' . $g_baseurl; } $g_css_index = 0; // Title of styleshee to use (empty if no preferences are set) $g_stylesheet_title = ""; $g_config = array('cssmedia' => isset($config['cssmedia']) ? $config['cssmedia'] : "screen", 'convert' => isset($config['convert']), 'media' => isset($config['media']) ? $config['media'] : "A4", 'scalepoints' => isset($config['scalepoints']), 'renderimages' => isset($config['renderimages']), 'renderfields' => isset($config['renderfields']), 'renderforms' => isset($config['renderforms']), 'pslevel' => isset($config['pslevel']) ? $config['pslevel'] : 2, 'renderlinks' => isset($config['renderlinks']), 'pagewidth' => isset($config['pixels']) ? (int) $config['pixels'] : 800, 'landscape' => isset($config['landscape']), 'method' => isset($config['method']) ? $config['method'] : "fpdf", 'margins' => array('left' => isset($config['leftmargin']) ? (int) $config['leftmargin'] : 0, 'right' => isset($config['rightmargin']) ? (int) $config['rightmargin'] : 0, 'top' => isset($config['topmargin']) ? (int) $config['topmargin'] : 0, 'bottom' => isset($config['bottommargin']) ? (int) $config['bottommargin'] : 0), 'encoding' => isset($config['encoding']) ? $config['encoding'] : "", 'ps2pdf' => isset($config['ps2pdf']) ? $config['ps2pdf'] : 0, 'compress' => isset($config['compress']) ? $config['compress'] : 0, 'output' => isset($config['output']) ? $config['output'] : 0, 'pdfversion' => isset($config['pdfversion']) ? $config['pdfversion'] : "1.2", 'transparency_workaround' => isset($config['transparency_workaround']), 'imagequality_workaround' => isset($config['imagequality_workaround']), 'draw_page_border' => isset($config['pageborder']), 'debugbox' => isset($config['debugbox']), 'watermarkhtml' => isset($config['watermarkhtml']), 'smartpagebreak' => isset($config['smartpagebreak']), 'html2xhtml' => !isset($config['html2xhtml']), 'mode' => 'html'); // ========== Entry point parse_config_file(HTML2PS_LOCATION . './.html2ps.config'); // validate input data if ($g_config['pagewidth'] == 0) { $me->error = "Please specify non-zero value for the pixel width!"; return false; } // begin processing $g_media = Media::predefined($g_config['media']); $g_media->set_landscape($g_config['landscape']); $g_media->set_margins($g_config['margins']); $g_media->set_pixels($g_config['pagewidth']); $g_px_scale = mm2pt($g_media->width() - $g_media->margins['left'] - $g_media->margins['right']) / $g_media->pixels; if ($g_config['scalepoints']) { $g_pt_scale = $g_px_scale * 1.43; // This is a magic number, just don't touch it, or everything will explode! } else { $g_pt_scale = 1.0; } // Initialize the coversion pipeline $pipeline = new Pipeline(); // Configure the fetchers $pipeline->fetchers[] = new FetcherURL(); // Configure the data filters $pipeline->data_filters[] = new DataFilterDoctype(); $pipeline->data_filters[] = new DataFilterUTF8($g_config['encoding']); if ($g_config['html2xhtml']) { $pipeline->data_filters[] = new DataFilterHTML2XHTML(); } else { $pipeline->data_filters[] = new DataFilterXHTML2XHTML(); } $pipeline->parser = new ParserXHTML(); $pipeline->pre_tree_filters = array(); if ($g_config['renderfields']) { $pipeline->pre_tree_filters[] = new PreTreeFilterHTML2PSFields("", "", ""); } if ($g_config['method'] === 'ps') { $pipeline->layout_engine = new LayoutEnginePS(); } else { $pipeline->layout_engine = new LayoutEngineDefault(); } $pipeline->post_tree_filters = array(); // Configure the output format if ($g_config['pslevel'] == 3) { $image_encoder = new PSL3ImageEncoderStream(); } else { $image_encoder = new PSL2ImageEncoderStream(); } switch ($g_config['method']) { case 'ps': $pipeline->output_driver = new OutputDriverPS($g_config['scalepoints'], $g_config['transparency_workaround'], $g_config['imagequality_workaround'], $image_encoder); break; case 'fastps': $pipeline->output_driver = new OutputDriverFastPS($image_encoder); break; case 'pdflib': $pipeline->output_driver = new OutputDriverPDFLIB($g_config['pdfversion']); break; case 'fpdf': $pipeline->output_driver = new OutputDriverFPDF(); break; default: $me->error = "Unknown output method"; return false; } if ($g_config['debugbox']) { $pipeline->output_driver->set_debug_boxes(true); } if ($g_config['draw_page_border']) { $pipeline->output_driver->set_show_page_border(true); } if ($g_config['ps2pdf']) { $pipeline->output_filters[] = new OutputFilterPS2PDF($g_config['pdfversion']); } if ($g_config['compress']) { $pipeline->output_filters[] = new OutputFilterGZip(); } $pipeline->destination = new DestinationBrowser($g_baseurl); $dest_filename = $pipeline->destination->filename_escape($pipeline->destination->get_filename()); ldSetContent("application/pdf"); if (!$me->cached("html2ps_" . md5($dest_filename))) { // Start the conversion $status = $pipeline->process($g_baseurl, $g_media); if ($status == null) { ldSetContent("text/html"); $me->error = "Error in conversion pipeline: " . $pipeline->error_message(); $me->savecache(0); return false; } else { $me->savecache(999); } } return true; }