├── CHANGELOG.md ├── LICENSE ├── composer.json ├── config └── dompdf.php ├── readme.md └── src ├── Facade └── Pdf.php ├── PDF.php └── ServiceProvider.php /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 5 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 6 | [3.0.0] 7 | Version 3.x supports DomPDF version 3.x. See the changelog in https://github.com/dompdf/dompdf/releases/tag/v3.0.0 8 | 9 | The most notable change in laravel-dompdf are the changed defaults, to be more secure; 10 | - `enable_remote` is now `false` by default. Change with caution. 11 | - `allowedRemoteHosts` and `artifactPathValidation` are added the the config. 12 | Also, support for Laravel < 9 and PHP < 8.1 is dropped. 13 | 14 | ## [3.1] 15 | This release updates the config for [dompdf/dompdf v3.1.0](https://github.com/dompdf/dompdf/releases/tag/v3.1.0) which contains the. following breaking URL: 16 | 17 | > **Breaking Change** 18 | > This release adds the "data://" scheme to the protocol validation rules. Installations that explicitly define the allowed protocols but do not include the "data://" protocol will no longer render data-URIs. This is a change from previous versions, where data-URIs were not processed through the validated rules. Installations that use the default validation rules included with Dompdf should see no impact. 19 | 20 | The update for laravel-dompdf adds this to the default config, but if you have published the config, you need to add the `data://` scheme. 21 | 22 | ## [3.0] 23 | 24 | Version 3.x supports DomPDF version 3.x. See the changelog in https://github.com/dompdf/dompdf/releases/tag/v3.0.0 25 | 26 | The most notable change in laravel-dompdf are the changed defaults, to be more secure; 27 | 28 | enable_remote is now false by default. Change with caution. 29 | allowedRemoteHosts and artifactPathValidation are added the the config. 30 | Also, support for Laravel < 9 and PHP < 8.1 is dropped. 31 | 32 | ## [2.2.0] 33 | ### What's Changed 34 | * Fix setOptions by @cesarreyes3 in https://github.com/barryvdh/laravel-dompdf/pull/1040 35 | * Bump dompdf minimum to 2.0.7 by @barryvdh 36 | 37 | ## New Contributors 38 | * @cesarreyes3 made their first contribution in https://github.com/barryvdh/laravel-dompdf/pull/1040 39 | 40 | **Full Changelog**: https://github.com/barryvdh/laravel-dompdf/compare/v2.1.1...v2.2.0 41 | 42 | ## [2.1.1] 43 | ### What's Changed 44 | * Revert "Fix setOptions method" by @barryvdh in https://github.com/barryvdh/laravel-dompdf/pull/1039 45 | 46 | **Full Changelog**: https://github.com/barryvdh/laravel-dompdf/compare/v2.1.0...v2.1.1 47 | 48 | ## [2.1.0] 49 | ### What's Changed 50 | * Convert phpunit by @barryvdh in https://github.com/barryvdh/laravel-dompdf/pull/952 51 | * ci: Use GitHub Actions V3 by @DannyvdSluijs in https://github.com/barryvdh/laravel-dompdf/pull/990 52 | * Fix named arguments when using facade by @erikn69 in https://github.com/barryvdh/laravel-dompdf/pull/1002 53 | * Update dompdf version as a dependancy by @AliSheikhDev in https://github.com/barryvdh/laravel-dompdf/pull/967 54 | * ci: Use GitHub Actions V4 by @erikn69 in https://github.com/barryvdh/laravel-dompdf/pull/1003 55 | * Fix phpstan analysis by @erikn69 in https://github.com/barryvdh/laravel-dompdf/pull/972 56 | * Fix setOptions method by @erikn69 in https://github.com/barryvdh/laravel-dompdf/pull/974 57 | * Small typo fix in dompdf config file by @ricklambrechts in https://github.com/barryvdh/laravel-dompdf/pull/1004 58 | * Upgrade to larastan/larastan by @parth391 in https://github.com/barryvdh/laravel-dompdf/pull/1014 59 | * Fixing "Upgrade to larastan/larastan" by @erikn69 in https://github.com/barryvdh/laravel-dompdf/pull/1018 60 | * Laravel 11 Support by @erikn69 in https://github.com/barryvdh/laravel-dompdf/pull/1036 61 | * Laravel 11.x Compatibility by @laravel-shift in https://github.com/barryvdh/laravel-dompdf/pull/1037 62 | 63 | ### New Contributors 64 | * @DannyvdSluijs made their first contribution in https://github.com/barryvdh/laravel-dompdf/pull/990 65 | * @AliSheikhDev made their first contribution in https://github.com/barryvdh/laravel-dompdf/pull/967 66 | * @ricklambrechts made their first contribution in https://github.com/barryvdh/laravel-dompdf/pull/1004 67 | * @parth391 made their first contribution in https://github.com/barryvdh/laravel-dompdf/pull/1014 68 | * @laravel-shift made their first contribution in https://github.com/barryvdh/laravel-dompdf/pull/1037 69 | 70 | **Full Changelog**: https://github.com/barryvdh/laravel-dompdf/compare/v2.0.1...v2.0.2 71 | 72 | ## [2.0.0] 73 | 74 | Version 2 supports DomPDF 2.x 75 | 76 | ### Changed 77 | - Remove the deprecated class 'Barryvdh\DomPDF\Facade' Facade in favor of Barryvdh\DomPDF\Facade\Pdf 78 | - Set default Facade to Pdf instead of PDF 79 | - HTML5 parser option is deprecated, because this is always on. 80 | - `orientation` option was never used. Removed in favor of `options.default_paper_orientation` 81 | 82 | ### Added 83 | - Upgraded to use dompdf/dompdf 2.x 84 | - `setOption` to change only the specified option(s), instead of replace all options. 85 | - Magic methods to allow calls to Dompdf methods easier. (#892) 86 | - `default_paper_orientation` option has been added to the defaults. 87 | - Add option to set public path (#890) 88 | 89 | ### Deprecated 90 | - `setOptions` is now deprecated. Use `setOption` instead. 91 | - Config `dompdf.defines` has been renamed to `dompdf.options` 92 | 93 | 94 | ## [2.0.0-beta3] 95 | ### Changed 96 | - Remove the deprecated class 'Barryvdh\DomPDF\Facade' Facade in favor of Barryvdh\DomPDF\Facade\Pdf 97 | - Set default Facade to Pdf instead of PDF 98 | 99 | ## [2.0.0-beta2] 100 | 101 | ### Added 102 | - Upgraded to use dompdf/dompdf 2.x 103 | - `setOption` to change only the specified option(s), instead of replace all options. 104 | - Magic methods to allow calls to Dompdf methods easier. (#892) 105 | - `default_paper_orientation` option has been added to the defaults. 106 | - Add option to set public path (#890) 107 | 108 | ### Changed 109 | - HTML5 parser option is deprecated, because this is always on. 110 | - `orientation` option was never used. Removed in favor of `options.default_paper_orientation` 111 | 112 | ### Deprecated 113 | - `setOptions` is now deprecated. Use `setOption` instead. 114 | - Config `dompdf.defines` has been renamed to `dompdf.options` 115 | 116 | 117 | ## Dompdf 2.0.0, highlights since 1.2.x 118 | > https://github.com/dompdf/dompdf/releases/tag/v2.0.0 119 | > - Addresses multiple security vulnerabilities (see link) 120 | > - Modifies callback and page_script/page_text handling (breaking change, see link) 121 | > - Switches the HTML5 parser to Masterminds/HTML5 122 | > - Improves CSS property parsing and representation 123 | > - Improves border, outline, and background rendering for inline elements 124 | > - Switches installed fonts and font metrics cache file format to JSON 125 | > - Adds support for the inset CSS shorthand property and the legacy break-word keyword for word-break 126 | > - Adds "end_document" callback event 127 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 barryvdh 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "barryvdh/laravel-dompdf", 3 | "description": "A DOMPDF Wrapper for Laravel", 4 | "license": "MIT", 5 | "keywords": [ 6 | "laravel", 7 | "dompdf", 8 | "pdf" 9 | ], 10 | "authors": [ 11 | { 12 | "name": "Barry vd. Heuvel", 13 | "email": "barryvdh@gmail.com" 14 | } 15 | ], 16 | "require": { 17 | "php": "^8.1", 18 | "dompdf/dompdf": "^3.0", 19 | "illuminate/support": "^9|^10|^11|^12" 20 | }, 21 | "require-dev": { 22 | "orchestra/testbench": "^7|^8|^9|^10", 23 | "squizlabs/php_codesniffer": "^3.5", 24 | "phpro/grumphp": "^2.5", 25 | "larastan/larastan": "^2.7|^3.0" 26 | }, 27 | "autoload": { 28 | "psr-4": { 29 | "Barryvdh\\DomPDF\\": "src" 30 | } 31 | }, 32 | "autoload-dev": { 33 | "psr-4": { 34 | "Barryvdh\\DomPDF\\Tests\\": "tests" 35 | } 36 | }, 37 | "extra": { 38 | "branch-alias": { 39 | "dev-master": "3.0-dev" 40 | }, 41 | "laravel": { 42 | "providers": [ 43 | "Barryvdh\\DomPDF\\ServiceProvider" 44 | ], 45 | "aliases": { 46 | "Pdf": "Barryvdh\\DomPDF\\Facade\\Pdf", 47 | "PDF": "Barryvdh\\DomPDF\\Facade\\Pdf" 48 | } 49 | } 50 | }, 51 | "scripts": { 52 | "test": "phpunit", 53 | "check-style": "phpcs -p --standard=psr12 src/", 54 | "fix-style": "phpcbf -p --standard=psr12 src/", 55 | "phpstan": "phpstan analyze --memory-limit=-1" 56 | }, 57 | "minimum-stability": "dev", 58 | "prefer-stable": true, 59 | "config": { 60 | "allow-plugins": { 61 | "phpro/grumphp": true 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /config/dompdf.php: -------------------------------------------------------------------------------- 1 | false, // Throw an Exception on warnings from dompdf 15 | 16 | 'public_path' => null, // Override the public path if needed 17 | 18 | /* 19 | * Dejavu Sans font is missing glyphs for converted entities, turn it off if you need to show € and £. 20 | */ 21 | 'convert_entities' => true, 22 | 23 | 'options' => [ 24 | /** 25 | * The location of the DOMPDF font directory 26 | * 27 | * The location of the directory where DOMPDF will store fonts and font metrics 28 | * Note: This directory must exist and be writable by the webserver process. 29 | * *Please note the trailing slash.* 30 | * 31 | * Notes regarding fonts: 32 | * Additional .afm font metrics can be added by executing load_font.php from command line. 33 | * 34 | * Only the original "Base 14 fonts" are present on all pdf viewers. Additional fonts must 35 | * be embedded in the pdf file or the PDF may not display correctly. This can significantly 36 | * increase file size unless font subsetting is enabled. Before embedding a font please 37 | * review your rights under the font license. 38 | * 39 | * Any font specification in the source HTML is translated to the closest font available 40 | * in the font directory. 41 | * 42 | * The pdf standard "Base 14 fonts" are: 43 | * Courier, Courier-Bold, Courier-BoldOblique, Courier-Oblique, 44 | * Helvetica, Helvetica-Bold, Helvetica-BoldOblique, Helvetica-Oblique, 45 | * Times-Roman, Times-Bold, Times-BoldItalic, Times-Italic, 46 | * Symbol, ZapfDingbats. 47 | */ 48 | 'font_dir' => storage_path('fonts'), // advised by dompdf (https://github.com/dompdf/dompdf/pull/782) 49 | 50 | /** 51 | * The location of the DOMPDF font cache directory 52 | * 53 | * This directory contains the cached font metrics for the fonts used by DOMPDF. 54 | * This directory can be the same as DOMPDF_FONT_DIR 55 | * 56 | * Note: This directory must exist and be writable by the webserver process. 57 | */ 58 | 'font_cache' => storage_path('fonts'), 59 | 60 | /** 61 | * The location of a temporary directory. 62 | * 63 | * The directory specified must be writeable by the webserver process. 64 | * The temporary directory is required to download remote images and when 65 | * using the PDFLib back end. 66 | */ 67 | 'temp_dir' => sys_get_temp_dir(), 68 | 69 | /** 70 | * ==== IMPORTANT ==== 71 | * 72 | * dompdf's "chroot": Prevents dompdf from accessing system files or other 73 | * files on the webserver. All local files opened by dompdf must be in a 74 | * subdirectory of this directory. DO NOT set it to '/' since this could 75 | * allow an attacker to use dompdf to read any files on the server. This 76 | * should be an absolute path. 77 | * This is only checked on command line call by dompdf.php, but not by 78 | * direct class use like: 79 | * $dompdf = new DOMPDF(); $dompdf->load_html($htmldata); $dompdf->render(); $pdfdata = $dompdf->output(); 80 | */ 81 | 'chroot' => realpath(base_path()), 82 | 83 | /** 84 | * Protocol whitelist 85 | * 86 | * Protocols and PHP wrappers allowed in URIs, and the validation rules 87 | * that determine if a resouce may be loaded. Full support is not guaranteed 88 | * for the protocols/wrappers specified 89 | * by this array. 90 | * 91 | * @var array 92 | */ 93 | 'allowed_protocols' => [ 94 | 'data://' => ['rules' => []], 95 | 'file://' => ['rules' => []], 96 | 'http://' => ['rules' => []], 97 | 'https://' => ['rules' => []], 98 | ], 99 | 100 | /** 101 | * Operational artifact (log files, temporary files) path validation 102 | */ 103 | 'artifactPathValidation' => null, 104 | 105 | /** 106 | * @var string 107 | */ 108 | 'log_output_file' => null, 109 | 110 | /** 111 | * Whether to enable font subsetting or not. 112 | */ 113 | 'enable_font_subsetting' => false, 114 | 115 | /** 116 | * The PDF rendering backend to use 117 | * 118 | * Valid settings are 'PDFLib', 'CPDF' (the bundled R&OS PDF class), 'GD' and 119 | * 'auto'. 'auto' will look for PDFLib and use it if found, or if not it will 120 | * fall back on CPDF. 'GD' renders PDFs to graphic files. 121 | * {@link * Canvas_Factory} ultimately determines which rendering class to 122 | * instantiate based on this setting. 123 | * 124 | * Both PDFLib & CPDF rendering backends provide sufficient rendering 125 | * capabilities for dompdf, however additional features (e.g. object, 126 | * image and font support, etc.) differ between backends. Please see 127 | * {@link PDFLib_Adapter} for more information on the PDFLib backend 128 | * and {@link CPDF_Adapter} and lib/class.pdf.php for more information 129 | * on CPDF. Also see the documentation for each backend at the links 130 | * below. 131 | * 132 | * The GD rendering backend is a little different than PDFLib and 133 | * CPDF. Several features of CPDF and PDFLib are not supported or do 134 | * not make any sense when creating image files. For example, 135 | * multiple pages are not supported, nor are PDF 'objects'. Have a 136 | * look at {@link GD_Adapter} for more information. GD support is 137 | * experimental, so use it at your own risk. 138 | * 139 | * @link http://www.pdflib.com 140 | * @link http://www.ros.co.nz/pdf 141 | * @link http://www.php.net/image 142 | */ 143 | 'pdf_backend' => 'CPDF', 144 | 145 | /** 146 | * html target media view which should be rendered into pdf. 147 | * List of types and parsing rules for future extensions: 148 | * http://www.w3.org/TR/REC-html40/types.html 149 | * screen, tty, tv, projection, handheld, print, braille, aural, all 150 | * Note: aural is deprecated in CSS 2.1 because it is replaced by speech in CSS 3. 151 | * Note, even though the generated pdf file is intended for print output, 152 | * the desired content might be different (e.g. screen or projection view of html file). 153 | * Therefore allow specification of content here. 154 | */ 155 | 'default_media_type' => 'screen', 156 | 157 | /** 158 | * The default paper size. 159 | * 160 | * North America standard is "letter"; other countries generally "a4" 161 | * 162 | * @see CPDF_Adapter::PAPER_SIZES for valid sizes ('letter', 'legal', 'A4', etc.) 163 | */ 164 | 'default_paper_size' => 'a4', 165 | 166 | /** 167 | * The default paper orientation. 168 | * 169 | * The orientation of the page (portrait or landscape). 170 | * 171 | * @var string 172 | */ 173 | 'default_paper_orientation' => 'portrait', 174 | 175 | /** 176 | * The default font family 177 | * 178 | * Used if no suitable fonts can be found. This must exist in the font folder. 179 | * 180 | * @var string 181 | */ 182 | 'default_font' => 'serif', 183 | 184 | /** 185 | * Image DPI setting 186 | * 187 | * This setting determines the default DPI setting for images and fonts. The 188 | * DPI may be overridden for inline images by explictly setting the 189 | * image's width & height style attributes (i.e. if the image's native 190 | * width is 600 pixels and you specify the image's width as 72 points, 191 | * the image will have a DPI of 600 in the rendered PDF. The DPI of 192 | * background images can not be overridden and is controlled entirely 193 | * via this parameter. 194 | * 195 | * For the purposes of DOMPDF, pixels per inch (PPI) = dots per inch (DPI). 196 | * If a size in html is given as px (or without unit as image size), 197 | * this tells the corresponding size in pt. 198 | * This adjusts the relative sizes to be similar to the rendering of the 199 | * html page in a reference browser. 200 | * 201 | * In pdf, always 1 pt = 1/72 inch 202 | * 203 | * Rendering resolution of various browsers in px per inch: 204 | * Windows Firefox and Internet Explorer: 205 | * SystemControl->Display properties->FontResolution: Default:96, largefonts:120, custom:? 206 | * Linux Firefox: 207 | * about:config *resolution: Default:96 208 | * (xorg screen dimension in mm and Desktop font dpi settings are ignored) 209 | * 210 | * Take care about extra font/image zoom factor of browser. 211 | * 212 | * In images, size in pixel attribute, img css style, are overriding 213 | * the real image dimension in px for rendering. 214 | * 215 | * @var int 216 | */ 217 | 'dpi' => 96, 218 | 219 | /** 220 | * Enable embedded PHP 221 | * 222 | * If this setting is set to true then DOMPDF will automatically evaluate embedded PHP contained 223 | * within tags. 224 | * 225 | * ==== IMPORTANT ==== Enabling this for documents you do not trust (e.g. arbitrary remote html pages) 226 | * is a security risk. 227 | * Embedded scripts are run with the same level of system access available to dompdf. 228 | * Set this option to false (recommended) if you wish to process untrusted documents. 229 | * This setting may increase the risk of system exploit. 230 | * Do not change this settings without understanding the consequences. 231 | * Additional documentation is available on the dompdf wiki at: 232 | * https://github.com/dompdf/dompdf/wiki 233 | * 234 | * @var bool 235 | */ 236 | 'enable_php' => false, 237 | 238 | /** 239 | * Enable inline JavaScript 240 | * 241 | * If this setting is set to true then DOMPDF will automatically insert JavaScript code contained 242 | * within tags as written into the PDF. 243 | * NOTE: This is PDF-based JavaScript to be executed by the PDF viewer, 244 | * not browser-based JavaScript executed by Dompdf. 245 | * 246 | * @var bool 247 | */ 248 | 'enable_javascript' => true, 249 | 250 | /** 251 | * Enable remote file access 252 | * 253 | * If this setting is set to true, DOMPDF will access remote sites for 254 | * images and CSS files as required. 255 | * 256 | * ==== IMPORTANT ==== 257 | * This can be a security risk, in particular in combination with isPhpEnabled and 258 | * allowing remote html code to be passed to $dompdf = new DOMPDF(); $dompdf->load_html(...); 259 | * This allows anonymous users to download legally doubtful internet content which on 260 | * tracing back appears to being downloaded by your server, or allows malicious php code 261 | * in remote html pages to be executed by your server with your account privileges. 262 | * 263 | * This setting may increase the risk of system exploit. Do not change 264 | * this settings without understanding the consequences. Additional 265 | * documentation is available on the dompdf wiki at: 266 | * https://github.com/dompdf/dompdf/wiki 267 | * 268 | * @var bool 269 | */ 270 | 'enable_remote' => false, 271 | 272 | /** 273 | * List of allowed remote hosts 274 | * 275 | * Each value of the array must be a valid hostname. 276 | * 277 | * This will be used to filter which resources can be loaded in combination with 278 | * isRemoteEnabled. If enable_remote is FALSE, then this will have no effect. 279 | * 280 | * Leave to NULL to allow any remote host. 281 | * 282 | * @var array|null 283 | */ 284 | 'allowed_remote_hosts' => null, 285 | 286 | /** 287 | * A ratio applied to the fonts height to be more like browsers' line height 288 | */ 289 | 'font_height_ratio' => 1.1, 290 | 291 | /** 292 | * Use the HTML5 Lib parser 293 | * 294 | * @deprecated This feature is now always on in dompdf 2.x 295 | * 296 | * @var bool 297 | */ 298 | 'enable_html5_parser' => true, 299 | ], 300 | 301 | ]; 302 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | ## DOMPDF Wrapper for Laravel 2 | 3 | ### Laravel wrapper for [Dompdf HTML to PDF Converter](https://github.com/dompdf/dompdf) 4 | 5 | [![Tests](https://github.com/barryvdh/laravel-dompdf/workflows/Tests/badge.svg)](https://github.com/barryvdh/laravel-dompdf/actions) 6 | [![Packagist License](https://img.shields.io/badge/Licence-MIT-blue)](http://choosealicense.com/licenses/mit/) 7 | [![Latest Stable Version](https://img.shields.io/packagist/v/barryvdh/laravel-dompdf?label=Stable)](https://packagist.org/packages/barryvdh/laravel-dompdf) 8 | [![Total Downloads](https://img.shields.io/packagist/dt/barryvdh/laravel-dompdf.svg?label=Downloads)](https://packagist.org/packages/barryvdh/laravel-dompdf) 9 | [![Fruitcake](https://img.shields.io/badge/Powered%20By-Fruitcake-b2bc35.svg)](https://fruitcake.nl/) 10 | 11 | ## Installation 12 | 13 | ### Laravel 14 | Require this package in your composer.json and update composer. This will download the package and the dompdf + fontlib libraries also. 15 | 16 | composer require barryvdh/laravel-dompdf 17 | 18 | ### Lumen 19 | 20 | After updating composer add the following lines to register provider in `bootstrap/app.php` 21 | 22 | ``` 23 | $app->register(\Barryvdh\DomPDF\ServiceProvider::class); 24 | ``` 25 | 26 | To change the configuration, copy the config file to your config folder and enable it in `bootstrap/app.php`: 27 | 28 | ``` 29 | $app->configure('dompdf'); 30 | ``` 31 | 32 | ## Using 33 | 34 | You can create a new DOMPDF instance and load a HTML string, file or view name. You can save it to a file, or stream (show in browser) or download. 35 | 36 | ```php 37 | use Barryvdh\DomPDF\Facade\Pdf; 38 | 39 | $pdf = Pdf::loadView('pdf.invoice', $data); 40 | return $pdf->download('invoice.pdf'); 41 | ``` 42 | 43 | or use the App container: 44 | 45 | ```php 46 | $pdf = App::make('dompdf.wrapper'); 47 | $pdf->loadHTML('

Test

'); 48 | return $pdf->stream(); 49 | ``` 50 | 51 | Or use the facade: 52 | 53 | You can chain the methods: 54 | 55 | ```php 56 | return Pdf::loadFile(public_path().'/myfile.html')->save('/path-to/my_stored_file.pdf')->stream('download.pdf'); 57 | ``` 58 | 59 | You can change the orientation and paper size, and hide or show errors (by default, errors are shown when debug is on) 60 | 61 | ```php 62 | Pdf::loadHTML($html)->setPaper('a4', 'landscape')->setWarnings(false)->save('myfile.pdf') 63 | ``` 64 | 65 | If you need the output as a string, you can get the rendered PDF with the output() function, so you can save/output it yourself. 66 | 67 | Use `php artisan vendor:publish` to create a config file located at `config/dompdf.php` which will allow you to define local configurations to change some settings (default paper etc). 68 | You can also use your ConfigProvider to set certain keys. 69 | 70 | ### Configuration 71 | The defaults configuration settings are set in `config/dompdf.php`. Copy this file to your own config directory to modify the values. You can publish the config using this command: 72 | ```shell 73 | php artisan vendor:publish --provider="Barryvdh\DomPDF\ServiceProvider" 74 | ``` 75 | 76 | You can still alter the dompdf options in your code before generating the pdf using this command: 77 | ```php 78 | Pdf::setOption(['dpi' => 150, 'defaultFont' => 'sans-serif']); 79 | ``` 80 | 81 | Available options and their defaults: 82 | * __rootDir__: "{app_directory}/vendor/dompdf/dompdf" 83 | * __tempDir__: "/tmp" _(available in config/dompdf.php)_ 84 | * __fontDir__: "{app_directory}/storage/fonts" _(available in config/dompdf.php)_ 85 | * __fontCache__: "{app_directory}/storage/fonts" _(available in config/dompdf.php)_ 86 | * __chroot__: "{app_directory}" _(available in config/dompdf.php)_ 87 | * __logOutputFile__: "/tmp/log.htm" 88 | * __defaultMediaType__: "screen" _(available in config/dompdf.php)_ 89 | * __defaultPaperSize__: "a4" _(available in config/dompdf.php)_ 90 | * __defaultFont__: "serif" _(available in config/dompdf.php)_ 91 | * __dpi__: 96 _(available in config/dompdf.php)_ 92 | * __fontHeightRatio__: 1.1 _(available in config/dompdf.php)_ 93 | * __isPhpEnabled__: false _(available in config/dompdf.php)_ 94 | * __isRemoteEnabled__: false _(available in config/dompdf.php)_ 95 | * __isJavascriptEnabled__: true _(available in config/dompdf.php)_ 96 | * __isHtml5ParserEnabled__: true _(available in config/dompdf.php)_ 97 | * __allowedRemoteHosts__: null _(available in config/dompdf.php)_ 98 | * __isFontSubsettingEnabled__: false _(available in config/dompdf.php)_ 99 | * __debugPng__: false 100 | * __debugKeepTemp__: false 101 | * __debugCss__: false 102 | * __debugLayout__: false 103 | * __debugLayoutLines__: true 104 | * __debugLayoutBlocks__: true 105 | * __debugLayoutInline__: true 106 | * __debugLayoutPaddingBox__: true 107 | * __pdfBackend__: "CPDF" _(available in config/dompdf.php)_ 108 | * __pdflibLicense__: "" 109 | * __adminUsername__: "user" 110 | * __adminPassword__: "password" 111 | * __artifactPathValidation__: null _(available in config/dompdf.php)_ 112 | 113 | #### Note: Since 3.x the remote access is disabled by default, to provide more security. Use with caution! 114 | 115 | ### Tip: UTF-8 support 116 | In your templates, set the UTF-8 Metatag: 117 | 118 | 119 | 120 | ### Tip: Page breaks 121 | You can use the CSS `page-break-before`/`page-break-after` properties to create a new page. 122 | 123 | 128 |

Page 1

129 |
130 |

Page 2

131 | 132 | ### License 133 | 134 | This DOMPDF Wrapper for Laravel is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT) 135 | -------------------------------------------------------------------------------- /src/Facade/Pdf.php: -------------------------------------------------------------------------------- 1 | $callbacks) 14 | * @method static BasePDF setCss(\Dompdf\Css\Stylesheet $css) 15 | * @method static BasePDF setDefaultView(string $defaultView, array $options) 16 | * @method static BasePDF setDom(\DOMDocument $dom) 17 | * @method static BasePDF setFontMetrics(\Dompdf\FontMetrics $fontMetrics) 18 | * @method static BasePDF setHttpContext(resource|array $httpContext) 19 | * @method static BasePDF setPaper(string|float[] $paper, string $orientation = 'portrait') 20 | * @method static BasePDF setProtocol(string $protocol) 21 | * @method static BasePDF setTree(\Dompdf\Frame\FrameTree $tree) 22 | * @method static BasePDF setWarnings(bool $warnings) 23 | * @method static BasePDF setOption(array|string $attribute, $value = null) 24 | * @method static BasePDF setOptions(array $options) 25 | * @method static BasePDF loadView(string $view, array $data = [], array $mergeData = [], ?string $encoding = null) 26 | * @method static BasePDF loadHTML(string $string, ?string $encoding = null) 27 | * @method static BasePDF loadFile(string $file) 28 | * @method static BasePDF addInfo(array $info) 29 | * @method static string output(array $options = []) 30 | * @method static BasePDF save() 31 | * @method static \Illuminate\Http\Response download(string $filename = 'document.pdf') 32 | * @method static \Illuminate\Http\Response stream(string $filename = 'document.pdf') 33 | */ 34 | class Pdf extends IlluminateFacade 35 | { 36 | /** 37 | * Get the registered name of the component. 38 | * 39 | * @return string 40 | */ 41 | protected static function getFacadeAccessor() 42 | { 43 | return 'dompdf.wrapper'; 44 | } 45 | 46 | /** 47 | * Handle dynamic, static calls to the object. 48 | * 49 | * @param string $method 50 | * @param array $args 51 | * @return mixed 52 | * 53 | * @throws \RuntimeException 54 | */ 55 | public static function __callStatic($method, $args) 56 | { 57 | /** @var \Illuminate\Contracts\Foundation\Application|null */ 58 | $app = static::getFacadeApplication(); 59 | if (! $app) { 60 | throw new RuntimeException('Facade application has not been set.'); 61 | } 62 | 63 | // Resolve a new instance, avoid using a cached instance 64 | $instance = $app->make(static::getFacadeAccessor()); 65 | 66 | return $instance->$method(...$args); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/PDF.php: -------------------------------------------------------------------------------- 1 | $callbacks) 27 | * @method PDF setCss(\Dompdf\Css\Stylesheet $css) 28 | * @method PDF setDefaultView(string $defaultView, array $options) 29 | * @method PDF setDom(\DOMDocument $dom) 30 | * @method PDF setFontMetrics(\Dompdf\FontMetrics $fontMetrics) 31 | * @method PDF setHttpContext(resource|array $httpContext) 32 | * @method PDF setPaper(string|float[] $paper, string $orientation = 'portrait') 33 | * @method PDF setProtocol(string $protocol) 34 | * @method PDF setTree(\Dompdf\Frame\FrameTree $tree) 35 | * @method string getBaseHost() 36 | * @method string getBasePath() 37 | * @method \Dompdf\Canvas getCanvas() 38 | * @method array getCallbacks() 39 | * @method \Dompdf\Css\Stylesheet getCss() 40 | * @method \DOMDocument getDom() 41 | * @method \Dompdf\FontMetrics getFontMetrics() 42 | * @method resource getHttpContext() 43 | * @method Options getOptions() 44 | * @method \Dompdf\Frame\FrameTree getTree() 45 | * @method string getPaperOrientation() 46 | * @method float[] getPaperSize() 47 | * @method string getProtocol() 48 | */ 49 | class PDF 50 | { 51 | /** @var Dompdf */ 52 | protected $dompdf; 53 | 54 | /** @var \Illuminate\Contracts\Config\Repository */ 55 | protected $config; 56 | 57 | /** @var \Illuminate\Filesystem\Filesystem */ 58 | protected $files; 59 | 60 | /** @var \Illuminate\Contracts\View\Factory */ 61 | protected $view; 62 | 63 | /** @var bool */ 64 | protected $rendered = false; 65 | 66 | /** @var bool */ 67 | protected $showWarnings; 68 | 69 | /** @var string */ 70 | protected $public_path; 71 | 72 | public function __construct(Dompdf $dompdf, ConfigRepository $config, Filesystem $files, ViewFactory $view) 73 | { 74 | $this->dompdf = $dompdf; 75 | $this->config = $config; 76 | $this->files = $files; 77 | $this->view = $view; 78 | 79 | $this->showWarnings = $this->config->get('dompdf.show_warnings', false); 80 | } 81 | 82 | /** 83 | * Get the DomPDF instance 84 | */ 85 | public function getDomPDF(): Dompdf 86 | { 87 | return $this->dompdf; 88 | } 89 | 90 | /** 91 | * Show or hide warnings 92 | */ 93 | public function setWarnings(bool $warnings): self 94 | { 95 | $this->showWarnings = $warnings; 96 | return $this; 97 | } 98 | 99 | /** 100 | * Load a HTML string 101 | * 102 | * @param string|null $encoding Not used yet 103 | */ 104 | public function loadHTML(string $string, ?string $encoding = null): self 105 | { 106 | $string = $this->convertEntities($string); 107 | $this->dompdf->loadHtml($string, $encoding); 108 | $this->rendered = false; 109 | return $this; 110 | } 111 | 112 | /** 113 | * Load a HTML file 114 | */ 115 | public function loadFile(string $file): self 116 | { 117 | $this->dompdf->loadHtmlFile($file); 118 | $this->rendered = false; 119 | return $this; 120 | } 121 | 122 | /** 123 | * Add metadata info 124 | * @param array $info 125 | */ 126 | public function addInfo(array $info): self 127 | { 128 | foreach ($info as $name => $value) { 129 | $this->dompdf->add_info($name, $value); 130 | } 131 | return $this; 132 | } 133 | 134 | /** 135 | * Load a View and convert to HTML 136 | * @param array $data 137 | * @param array $mergeData 138 | * @param string|null $encoding Not used yet 139 | */ 140 | public function loadView(string $view, array $data = [], array $mergeData = [], ?string $encoding = null): self 141 | { 142 | $html = $this->view->make($view, $data, $mergeData)->render(); 143 | return $this->loadHTML($html, $encoding); 144 | } 145 | 146 | /** 147 | * Set/Change an option (or array of options) in Dompdf 148 | * 149 | * @param array|string $attribute 150 | * @param null|mixed $value 151 | */ 152 | public function setOption($attribute, $value = null): self 153 | { 154 | $this->dompdf->getOptions()->set($attribute, $value); 155 | return $this; 156 | } 157 | 158 | /** 159 | * Replace all the Options from DomPDF 160 | * 161 | * @param array $options 162 | */ 163 | public function setOptions(array $options, bool $mergeWithDefaults = false): self 164 | { 165 | if ($mergeWithDefaults) { 166 | $options = array_merge(app()->make('dompdf.options'), $options); 167 | } 168 | 169 | $this->dompdf->setOptions(new Options($options)); 170 | return $this; 171 | } 172 | 173 | /** 174 | * Output the PDF as a string. 175 | * 176 | * The options parameter controls the output. Accepted options are: 177 | * 178 | * 'compress' = > 1 or 0 - apply content stream compression, this is 179 | * on (1) by default 180 | * 181 | * @param array $options 182 | * 183 | * @return string The rendered PDF as string 184 | */ 185 | public function output(array $options = []): string 186 | { 187 | if (!$this->rendered) { 188 | $this->render(); 189 | } 190 | return (string) $this->dompdf->output($options); 191 | } 192 | 193 | /** 194 | * Save the PDF to a file 195 | */ 196 | public function save(string $filename, ?string $disk = null): self 197 | { 198 | $disk = $disk ?: $this->config->get('dompdf.disk'); 199 | 200 | if (! is_null($disk)) { 201 | Storage::disk($disk)->put($filename, $this->output()); 202 | return $this; 203 | } 204 | 205 | $this->files->put($filename, $this->output()); 206 | return $this; 207 | } 208 | 209 | /** 210 | * Make the PDF downloadable by the user 211 | */ 212 | public function download(string $filename = 'document.pdf'): Response 213 | { 214 | $output = $this->output(); 215 | $fallback = $this->fallbackName($filename); 216 | 217 | return new Response($output, 200, [ 218 | 'Content-Type' => 'application/pdf', 219 | 'Content-Disposition' => HeaderUtils::makeDisposition('attachment', $filename, $fallback), 220 | 'Content-Length' => strlen($output), 221 | ]); 222 | } 223 | 224 | /** 225 | * Return a response with the PDF to show in the browser 226 | */ 227 | public function stream(string $filename = 'document.pdf'): Response 228 | { 229 | $output = $this->output(); 230 | $fallback = $this->fallbackName($filename); 231 | 232 | 233 | return new Response($output, 200, [ 234 | 'Content-Type' => 'application/pdf', 235 | 'Content-Disposition' => HeaderUtils::makeDisposition('inline', $filename, $fallback), 236 | ]); 237 | } 238 | 239 | /** 240 | * Render the PDF 241 | */ 242 | public function render(): void 243 | { 244 | $this->dompdf->render(); 245 | 246 | if ($this->showWarnings) { 247 | global $_dompdf_warnings; 248 | if (!empty($_dompdf_warnings) && count($_dompdf_warnings)) { 249 | $warnings = ''; 250 | foreach ($_dompdf_warnings as $msg) { 251 | $warnings .= $msg . "\n"; 252 | } 253 | // $warnings .= $this->dompdf->get_canvas()->get_cpdf()->messages; 254 | if (!empty($warnings)) { 255 | throw new Exception($warnings); 256 | } 257 | } 258 | } 259 | $this->rendered = true; 260 | } 261 | 262 | /** @param array $pc */ 263 | public function setEncryption(string $password, string $ownerpassword = '', array $pc = []): void 264 | { 265 | $this->render(); 266 | $canvas = $this->dompdf->getCanvas(); 267 | if (! $canvas instanceof CPDF) { 268 | throw new \RuntimeException('Encryption is only supported when using CPDF'); 269 | } 270 | $canvas->get_cpdf()->setEncryption($password, $ownerpassword, $pc); 271 | } 272 | 273 | protected function convertEntities(string $subject): string 274 | { 275 | if (false === $this->config->get('dompdf.convert_entities', true)) { 276 | return $subject; 277 | } 278 | 279 | $entities = [ 280 | '€' => '€', 281 | '£' => '£', 282 | ]; 283 | 284 | foreach ($entities as $search => $replace) { 285 | $subject = str_replace($search, $replace, $subject); 286 | } 287 | return $subject; 288 | } 289 | 290 | /** 291 | * Dynamically handle calls into the dompdf instance. 292 | * 293 | * @param string $method 294 | * @param array $parameters 295 | * @return $this|mixed 296 | */ 297 | public function __call($method, $parameters) 298 | { 299 | if (method_exists($this, $method)) { 300 | return $this->$method(...$parameters); 301 | } 302 | 303 | if (method_exists($this->dompdf, $method)) { 304 | $return = $this->dompdf->$method(...$parameters); 305 | 306 | return $return == $this->dompdf ? $this : $return; 307 | } 308 | 309 | throw new \UnexpectedValueException("Method [{$method}] does not exist on PDF instance."); 310 | } 311 | 312 | /** 313 | * Make a safe fallback filename 314 | */ 315 | protected function fallbackName(string $filename): string 316 | { 317 | return str_replace('%', '', Str::ascii($filename)); 318 | } 319 | } 320 | -------------------------------------------------------------------------------- /src/ServiceProvider.php: -------------------------------------------------------------------------------- 1 | mergeConfigFrom($configPath, 'dompdf'); 29 | 30 | $this->app->bind('dompdf.options', function ($app) { 31 | $defines = $app['config']->get('dompdf.defines'); 32 | 33 | if ($defines) { 34 | $options = []; 35 | /** 36 | * @var string $key 37 | * @var mixed $value 38 | */ 39 | foreach ($defines as $key => $value) { 40 | $key = strtolower(str_replace('DOMPDF_', '', $key)); 41 | $options[$key] = $value; 42 | } 43 | } else { 44 | $options = $app['config']->get('dompdf.options'); 45 | } 46 | 47 | return $options; 48 | }); 49 | 50 | $this->app->bind('dompdf', function ($app) { 51 | 52 | $options = $app->make('dompdf.options'); 53 | $dompdf = new Dompdf($options); 54 | $path = realpath($app['config']->get('dompdf.public_path') ?: base_path('public')); 55 | if ($path === false) { 56 | throw new \RuntimeException('Cannot resolve public path'); 57 | } 58 | $dompdf->setBasePath($path); 59 | 60 | return $dompdf; 61 | }); 62 | $this->app->alias('dompdf', Dompdf::class); 63 | 64 | $this->app->bind('dompdf.wrapper', function ($app) { 65 | return new PDF($app['dompdf'], $app['config'], $app['files'], $app['view']); 66 | }); 67 | } 68 | 69 | /** 70 | * Check if package is running under Lumen app 71 | */ 72 | protected function isLumen(): bool 73 | { 74 | return Str::contains($this->app->version(), 'Lumen') === true; 75 | } 76 | 77 | public function boot(): void 78 | { 79 | if (! $this->isLumen()) { 80 | $configPath = __DIR__ . '/../config/dompdf.php'; 81 | $this->publishes([$configPath => config_path('dompdf.php')], 'config'); 82 | } 83 | } 84 | 85 | /** 86 | * Get the services provided by the provider. 87 | * 88 | * @return array 89 | */ 90 | public function provides(): array 91 | { 92 | return ['dompdf', 'dompdf.options', 'dompdf.wrapper']; 93 | } 94 | } 95 | --------------------------------------------------------------------------------