Example #1
0
 /**
  * Resolve and fetch an image for use.
  *
  * @param string $url       The url of the image
  * @param string $protocol  Default protocol if none specified in $url
  * @param string $host      Default host if none specified in $url
  * @param string $base_path Default path if none specified in $url
  * @param Dompdf $dompdf    The Dompdf instance
  *
  * @throws ImageException
  * @return array             An array with two elements: The local path to the image and the image extension
  */
 static function resolve_url($url, $protocol, $host, $base_path, Dompdf $dompdf)
 {
     self::$_dompdf = $dompdf;
     $protocol = mb_strtolower($protocol);
     $parsed_url = Helpers::explode_url($url);
     $message = null;
     $remote = $protocol && $protocol !== "file://" || $parsed_url['protocol'] != "";
     $data_uri = strpos($parsed_url['protocol'], "data:") === 0;
     $full_url = null;
     $enable_remote = $dompdf->get_option("enable_remote");
     try {
         // Remote not allowed and is not DataURI
         if (!$enable_remote && $remote && !$data_uri) {
             throw new ImageException("Remote file access is disabled.", E_WARNING);
         } else {
             if ($enable_remote && $remote || $data_uri) {
                 // Download remote files to a temporary directory
                 $full_url = Helpers::build_url($protocol, $host, $base_path, $url);
                 // From cache
                 if (isset(self::$_cache[$full_url])) {
                     $resolved_url = self::$_cache[$full_url];
                 } else {
                     $tmp_dir = $dompdf->get_option("temp_dir");
                     $resolved_url = tempnam($tmp_dir, "ca_dompdf_img_");
                     $image = "";
                     if ($data_uri) {
                         if ($parsed_data_uri = Helpers::parse_data_uri($url)) {
                             $image = $parsed_data_uri['data'];
                         }
                     } else {
                         set_error_handler(array("\\Dompdf\\Helpers", "record_warnings"));
                         $image = file_get_contents($full_url, null, $dompdf->getHttpContext());
                         restore_error_handler();
                     }
                     // Image not found or invalid
                     if (strlen($image) == 0) {
                         $msg = $data_uri ? "Data-URI could not be parsed" : "Image not found";
                         throw new ImageException($msg, E_WARNING);
                     } else {
                         //e.g. fetch.php?media=url.jpg&cache=1
                         //- Image file name might be one of the dynamic parts of the url, don't strip off!
                         //- a remote url does not need to have a file extension at all
                         //- local cached file does not have a matching file extension
                         //Therefore get image type from the content
                         file_put_contents($resolved_url, $image);
                     }
                 }
             } else {
                 $resolved_url = Helpers::build_url($protocol, $host, $base_path, $url);
             }
         }
         // Check if the local file is readable
         if (!is_readable($resolved_url) || !filesize($resolved_url)) {
             throw new ImageException("Image not readable or empty", E_WARNING);
         } else {
             list($width, $height, $type) = Helpers::dompdf_getimagesize($resolved_url, $dompdf->getHttpContext());
             // Known image type
             if ($width && $height && in_array($type, array("gif", "png", "jpeg", "bmp", "svg"))) {
                 //Don't put replacement image into cache - otherwise it will be deleted on cache cleanup.
                 //Only execute on successful caching of remote image.
                 if ($enable_remote && $remote || $data_uri) {
                     self::$_cache[$full_url] = $resolved_url;
                 }
             } else {
                 throw new ImageException("Image type unknown", E_WARNING);
             }
         }
     } catch (ImageException $e) {
         $resolved_url = self::$broken_image;
         $type = "png";
         $message = "Image not found or type unknown";
         Helpers::record_warnings($e->getCode(), $e->getMessage() . " \n {$url}", $e->getFile(), $e->getLine());
     }
     return array($resolved_url, $type, $message);
 }
Example #2
0
 /**
  * Add a link to the pdf
  *
  * @param string $url The url to link to
  * @param float $x The x position of the link
  * @param float $y The y position of the link
  * @param float $width The width of the link
  * @param float $height The height of the link
  */
 function add_link($url, $x, $y, $width, $height)
 {
     $y = $this->y($y) - $height;
     if (strpos($url, '#') === 0) {
         // Local link
         $name = substr($url, 1);
         if ($name) {
             $this->_pdf->create_annotation($x, $y, $x + $width, $y + $height, 'Link', "contents={$url} destname=" . substr($url, 1) . " linewidth=0");
         }
     } else {
         list($proto, $host, $path, $file) = Helpers::explode_url($url);
         if ($proto == "" || $proto === "file://") {
             return;
         }
         // Local links are not allowed
         $url = Helpers::build_url($proto, $host, $path, $file);
         $url = '{' . rawurldecode($url) . '}';
         $action = $this->_pdf->create_action("URI", "url=" . $url);
         $this->_pdf->create_annotation($x, $y, $x + $width, $y + $height, 'Link', "contents={$url} action={activate={$action}} linewidth=0");
     }
 }
Example #3
0
 protected function _image($val)
 {
     $DEBUGCSS = $this->_stylesheet->get_dompdf()->getOptions()->getDebugCss();
     $parsed_url = "none";
     if (mb_strpos($val, "url") === false) {
         $path = "none";
         //Don't resolve no image -> otherwise would prefix path and no longer recognize as none
     } else {
         $val = preg_replace("/url\\(['\"]?([^'\")]+)['\"]?\\)/", "\\1", trim($val));
         // Resolve the url now in the context of the current stylesheet
         $parsed_url = Helpers::explode_url($val);
         if ($parsed_url["protocol"] == "" && $this->_stylesheet->get_protocol() == "") {
             if ($parsed_url["path"][0] === '/' || $parsed_url["path"][0] === '\\') {
                 $path = $_SERVER["DOCUMENT_ROOT"] . '/';
             } else {
                 $path = $this->_stylesheet->get_base_path();
             }
             $path .= $parsed_url["path"] . $parsed_url["file"];
             $path = realpath($path);
             // If realpath returns FALSE then specifically state that there is no background image
             if (!$path) {
                 $path = 'none';
             }
         } else {
             $path = Helpers::build_url($this->_stylesheet->get_protocol(), $this->_stylesheet->get_host(), $this->_stylesheet->get_base_path(), $val);
         }
     }
     if ($DEBUGCSS) {
         print "<pre>[_image\n";
         print_r($parsed_url);
         print $this->_stylesheet->get_protocol() . "\n" . $this->_stylesheet->get_base_path() . "\n" . $path . "\n";
         print "_image]</pre>";
     }
     return $path;
 }
Example #4
0
 /**
  * Builds the {@link FrameTree}, loads any CSS and applies the styles to
  * the {@link FrameTree}
  */
 private function processHtml()
 {
     $this->tree->build_tree();
     $this->css->load_css_file(Stylesheet::getDefaultStylesheet(), Stylesheet::ORIG_UA);
     $acceptedmedia = Stylesheet::$ACCEPTED_GENERIC_MEDIA_TYPES;
     $acceptedmedia[] = $this->options->getDefaultMediaType();
     // <base href="" />
     $base_nodes = $this->dom->getElementsByTagName("base");
     if ($base_nodes->length && ($href = $base_nodes->item(0)->getAttribute("href"))) {
         list($this->protocol, $this->baseHost, $this->basePath) = Helpers::explode_url($href);
     }
     // Set the base path of the Stylesheet to that of the file being processed
     $this->css->set_protocol($this->protocol);
     $this->css->set_host($this->baseHost);
     $this->css->set_base_path($this->basePath);
     // Get all the stylesheets so that they are processed in document order
     $xpath = new DOMXPath($this->dom);
     $stylesheets = $xpath->query("//*[name() = 'link' or name() = 'style']");
     foreach ($stylesheets as $tag) {
         switch (strtolower($tag->nodeName)) {
             // load <link rel="STYLESHEET" ... /> tags
             case "link":
                 if (mb_strtolower(stripos($tag->getAttribute("rel"), "stylesheet") !== false) || mb_strtolower($tag->getAttribute("type")) === "text/css") {
                     //Check if the css file is for an accepted media type
                     //media not given then always valid
                     $formedialist = preg_split("/[\\s\n,]/", $tag->getAttribute("media"), -1, PREG_SPLIT_NO_EMPTY);
                     if (count($formedialist) > 0) {
                         $accept = false;
                         foreach ($formedialist as $type) {
                             if (in_array(mb_strtolower(trim($type)), $acceptedmedia)) {
                                 $accept = true;
                                 break;
                             }
                         }
                         if (!$accept) {
                             //found at least one mediatype, but none of the accepted ones
                             //Skip this css file.
                             continue;
                         }
                     }
                     $url = $tag->getAttribute("href");
                     $url = Helpers::build_url($this->protocol, $this->baseHost, $this->basePath, $url);
                     $this->css->load_css_file($url, Stylesheet::ORIG_AUTHOR);
                 }
                 break;
                 // load <style> tags
             // load <style> tags
             case "style":
                 // Accept all <style> tags by default (note this is contrary to W3C
                 // HTML 4.0 spec:
                 // http://www.w3.org/TR/REC-html40/present/styles.html#adef-media
                 // which states that the default media type is 'screen'
                 if ($tag->hasAttributes() && ($media = $tag->getAttribute("media")) && !in_array($media, $acceptedmedia)) {
                     continue;
                 }
                 $css = "";
                 if ($tag->hasChildNodes()) {
                     $child = $tag->firstChild;
                     while ($child) {
                         $css .= $child->nodeValue;
                         // Handle <style><!-- blah --></style>
                         $child = $child->nextSibling;
                     }
                 } else {
                     $css = $tag->nodeValue;
                 }
                 $this->css->load_css($css);
                 break;
         }
     }
 }