├── LICENSE.md ├── Module.php ├── README.md ├── composer.json ├── config └── module.config.php └── src └── DOMPDFModule ├── Module.php ├── Mvc └── Service │ ├── ViewPdfRendererFactory.php │ └── ViewPdfStrategyFactory.php ├── Service └── DOMPDFFactory.php └── View ├── Model └── PdfModel.php ├── Renderer └── PdfRenderer.php └── Strategy └── PdfStrategy.php /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 University of Maine, 2016 Raymond J. Kolbe 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /Module.php: -------------------------------------------------------------------------------- 1 | 16 | * @copyright Copyright (c) 2012 University of Maine, 2016 Raymond J. Kolbe 17 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 18 | */ 19 | 20 | require_once __DIR__ . '/src/DOMPDFModule/Module.php'; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | DOMPDFModule 2 | ============ 3 | 4 | [![Build Status](https://secure.travis-ci.org/raykolbe/DOMPDFModule.png?branch=master)](http://travis-ci.org/raykolbe/DOMPDFModule) [![Code Climate](https://codeclimate.com/github/raykolbe/DOMPDFModule/badges/gpa.svg)](https://codeclimate.com/github/raykolbe/DOMPDFModule) [![Test Coverage](https://codeclimate.com/github/raykolbe/DOMPDFModule/badges/coverage.svg)](https://codeclimate.com/github/raykolbe/DOMPDFModule/coverage) [![Total Downloads](https://poser.pugx.org/dino/dompdf-module/downloads)](https://packagist.org/packages/dino/dompdf-module) [![License](https://poser.pugx.org/dino/dompdf-module/license)](https://packagist.org/packages/dino/dompdf-module) 5 | 6 | The DOMPDF module integrates the DOMPDF library with Zend Framework 2 with minimal effort on the consumer's end. 7 | 8 | ## Requirements 9 | - [Zend Framework 2](http://www.github.com/zendframework/zf2) 10 | 11 | ## Installation 12 | Installation of DOMPDFModule uses PHP Composer. For more information about 13 | PHP Composer, please visit the official [PHP Composer site](http://getcomposer.org/). 14 | 15 | #### Installation steps 16 | 17 | 1. `cd my/project/directory` 18 | 2. create a `composer.json` file with following contents: 19 | 20 | ```json 21 | { 22 | "require": { 23 | "dino/dompdf-module": "dev-master" 24 | } 25 | } 26 | ``` 27 | 3. install PHP Composer via `curl -s http://getcomposer.org/installer | php` (on windows, download 28 | http://getcomposer.org/installer and execute it with PHP) 29 | 4. run `php composer.phar install` 30 | 5. open `my/project/directory/config/application.config.php` and add the following key to your `modules`: 31 | 32 | ```php 33 | 'DOMPDFModule', 34 | ``` 35 | #### Configuration options 36 | You can override options via the `dompdf_module` key in your local or global config files. See DOMPDFModule/config/module.config.php for config options. 37 | 38 | ## Usage 39 | 40 | ```php 41 | setOption('fileName', 'monthly-report'); // "pdf" extension is automatically appended 54 | $pdf->setOption('display', PdfModel::DISPLAY_ATTACHMENT); // Triggers browser to prompt "save as" dialog 55 | $pdf->setOption('paperSize', 'a4'); // Defaults to "8x11" 56 | $pdf->setOption('paperOrientation', 'landscape'); // Defaults to "portrait" 57 | 58 | // To set view variables 59 | $pdf->setVariables(array( 60 | 'message' => 'Hello' 61 | )); 62 | 63 | return $pdf; 64 | } 65 | } 66 | ``` 67 | ## Development 68 | So you want to contribute? Fantastic! Don't worry, it's easy. Local builds, tests, and code quality checks can be executed using [Docker](https://www.docker.com/). 69 | 70 | ### Quick Start 71 | 1. Install [Docker CE](https://www.docker.com/community-edition). 72 | 2. Run the following from your terminal: 73 | 74 | ``` 75 | docker build -t dino/dompdf-module . 76 | docker run -v composer-cache:/var/lib/composer -v ${PWD}:/opt/app dino/dompdf-module 77 | ``` 78 | 79 | Super easy, right? Here's a quick walk through as to what's going on. 80 | 81 | * `docker build -t dino/dompdf-module .` builds a docker image that will be used for each run (i.e. each time `docker run` is executed) and tags it with the name `dino/dompdf-module`. 82 | * `docker run -v composer-cache:/var/lib/composer -v ${PWD}:/opt/app dino/dompdf-module` runs the default build in a new Docker container derived from the image tagged `dino/dompdf-module`. The root of the project and PHP Composer cache volume are mounted so that artifacts generated during the build process are available to you on your local machine. 83 | 84 | **Note:** You only need to run the first command once in order to build the image. The second command is what executes the build (build, tests, code quality checks, etc.). 85 | 86 | ### Other Supported PHP Versions 87 | By default, builds executed using Docker are done so using the [latest stable version of PHP](http://php.net/supported-versions.php). If you're adventurous you can execute builds against other [supported versions](http://php.net/supported-versions.php) of PHP. 88 | 89 | **PHP 5.6** 90 | 91 | ``` 92 | docker build --build-arg PHP_VERSION=5.6 --tag dino/dompdf-module-php56 . 93 | docker run -v composer-cache:/var/lib/composer -v ${PWD}:/opt/app dino/dompdf-module-php56 94 | ``` 95 | 96 | ## To-do 97 | - Add command line support. 98 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dino/dompdf-module", 3 | "type": "library", 4 | "description": "A Zend Framework 2 module for incorporating DOMPDF support.", 5 | "keywords": ["pdf","dompdf", "zf2"], 6 | "homepage": "http://raymondkolbe.com", 7 | "license": "MIT", 8 | "authors": [ 9 | { 10 | "name": "Raymond J. Kolbe", 11 | "email": "rkolbe@gmail.com" 12 | } 13 | ], 14 | "require": { 15 | "php": ">=5.6", 16 | "zendframework/zend-loader": "^2.4", 17 | "zendframework/zend-servicemanager": "^2.4", 18 | "zendframework/zend-modulemanager": "^2.4", 19 | "zendframework/zend-mvc": "^2.4", 20 | "zendframework/zend-view": "^2.4", 21 | "zendframework/zend-serializer": "^2.4", 22 | "zendframework/zend-log": "^2.4", 23 | "zendframework/zend-i18n": "^2.4", 24 | "zendframework/zend-http": "^2.4", 25 | "zendframework/zend-console": "^2.4", 26 | "dompdf/dompdf": "^0.8.0" 27 | }, 28 | "require-dev": { 29 | "phpunit/phpunit": "^4.8.27", 30 | "codeclimate/php-test-reporter": "^0.3.2", 31 | "fabpot/php-cs-fixer": "^1.12", 32 | "squizlabs/php_codesniffer": "^2.7", 33 | "phpmd/phpmd": "^2.4" 34 | }, 35 | "autoload": { 36 | "psr-0": { 37 | "DOMPDFModule": "src/" 38 | } 39 | }, 40 | "autoload-dev": { 41 | "psr-0": { 42 | "DOMPDFModuleTest": "tests/" 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /config/module.config.php: -------------------------------------------------------------------------------- 1 | 16 | * @copyright Copyright (c) 2012 University of Maine, 2016 Raymond J. Kolbe 17 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 18 | */ 19 | 20 | namespace DOMPDFModule; 21 | 22 | return [ 23 | 'dompdf_module' => [ 24 | /** 25 | * The location of the DOMPDF font directory 26 | * 27 | * If DOMPDF_FONT_DIR identical to DOMPDF_FONT_CACHE or user executing DOMPDF from the CLI, 28 | * this directory must 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 and could violate copyright provisions of a font. Font subsetting is 37 | * not currently supported. 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, 47 | * ZapfDingbats, 48 | * 49 | * *Please note the trailing slash.* 50 | */ 51 | 'font_directory' => __DIR__ . '/../../../dompdf/dompdf/lib/fonts/', 52 | 53 | /** 54 | * The location of the DOMPDF font cache directory 55 | * 56 | * Note this directory must be writable by the webserver process 57 | * This folder must already exist! 58 | * It contains the .afm files, on demand parsed, converted to php syntax and cached 59 | * This folder can be the same as DOMPDF_FONT_DIR 60 | */ 61 | 'font_cache_directory' => __DIR__ . '/../../../dompdf/dompdf/lib/fonts/', 62 | 63 | /** 64 | * The location of a temporary directory. 65 | * 66 | * The directory specified must be writeable by the webserver process. 67 | * The temporary directory is required to download remote images and when 68 | * using the PFDLib back end. 69 | */ 70 | 'temporary_directory' => sys_get_temp_dir(), 71 | 72 | /** 73 | * ==== IMPORTANT ==== 74 | * 75 | * dompdf's "chroot": Prevents dompdf from accessing system files or other 76 | * files on the webserver. All local files opened by dompdf must be in a 77 | * subdirectory of this directory. DO NOT set it to '/' since this could 78 | * allow an attacker to use dompdf to read any files on the server. This 79 | * should be an absolute path. 80 | * This is only checked on command line call by dompdf.php, but not by 81 | * direct class use like: 82 | * $dompdf = new DOMPDF(); $dompdf->load_html($htmldata); $dompdf->render(); $pdfdata = $dompdf->output(); 83 | */ 84 | 'chroot' => realpath(__DIR__ . '/../../../dompdf/dompdf/'), 85 | 86 | /** 87 | * Whether to make font subsetting or not. 88 | */ 89 | 'enable_fontsubsetting' => false, 90 | 91 | /** 92 | * The PDF rendering backend to use 93 | * 94 | * Valid settings are 'PDFLib', 'CPDF' (the bundled R&OS PDF class), 'GD' and 95 | * 'auto'. 'auto' will look for PDFLib and use it if found, or if not it will 96 | * fall back on CPDF. 'GD' renders PDFs to graphic files. {@link 97 | * Canvas_Factory} ultimately determines which rendering class to instantiate 98 | * based on this setting. 99 | * 100 | * Both PDFLib & CPDF rendering backends provide sufficient rendering 101 | * capabilities for dompdf, however additional features (e.g. object, 102 | * image and font support, etc.) differ between backends. Please see 103 | * {@link PDFLib_Adapter} for more information on the PDFLib backend 104 | * and {@link CPDF_Adapter} and lib/class.pdf.php for more information 105 | * on CPDF. Also see the documentation for each backend at the links 106 | * below. 107 | * 108 | * The GD rendering backend is a little different than PDFLib and 109 | * CPDF. Several features of CPDF and PDFLib are not supported or do 110 | * not make any sense when creating image files. For example, 111 | * multiple pages are not supported, nor are PDF 'objects'. Have a 112 | * look at {@link GD_Adapter} for more information. GD support is new 113 | * and experimental, so use it at your own risk. 114 | * 115 | * @link http://www.pdflib.com 116 | * @link http://www.ros.co.nz/pdf 117 | * @link http://www.php.net/image 118 | */ 119 | 'pdf_backend' => 'CPDF', 120 | 121 | /** 122 | * html target media view which should be rendered into pdf. 123 | * List of types and parsing rules for future extensions: 124 | * http://www.w3.org/TR/REC-html40/types.html 125 | * screen, tty, tv, projection, handheld, print, braille, aural, all 126 | * Note: aural is deprecated in CSS 2.1 because it is replaced by speech in CSS 3. 127 | * Note, even though the generated pdf file is intended for print output, 128 | * the desired content might be different (e.g. screen or projection view of html file). 129 | * Therefore allow specification of content here. 130 | */ 131 | 'default_media_type' => 'screen', 132 | 133 | /** 134 | * PDFlib license key 135 | * 136 | * If you are using a licensed, commercial version of PDFlib, specify 137 | * your license key here. If you are using PDFlib-Lite or are evaluating 138 | * the commercial version of PDFlib, comment out this setting. 139 | * 140 | * @link http://www.pdflib.com 141 | * 142 | * If pdflib present in web server and auto or selected explicitely above, 143 | * a real license code must exist! 144 | */ 145 | 'pdflib_license' => '', 146 | 147 | /** 148 | * The default paper size. 149 | * 150 | * North America standard is "letter"; other countries generally "a4" 151 | * 152 | * @see CPDF_Adapter::PAPER_SIZES for valid sizes 153 | */ 154 | 'default_paper_size' => 'letter', 155 | 156 | /** 157 | * The default font family 158 | * 159 | * Used if no suitable fonts can be found. This must exist in the font folder. 160 | * @var string 161 | */ 162 | 'default_font' => 'serif', 163 | 164 | /** 165 | * Image DPI setting 166 | * 167 | * This setting determines the default DPI setting for images and fonts. The 168 | * DPI may be overridden for inline images by explictly setting the 169 | * image's width & height style attributes (i.e. if the image's native 170 | * width is 600 pixels and you specify the image's width as 72 points, 171 | * the image will have a DPI of 600 in the rendered PDF. The DPI of 172 | * background images can not be overridden and is controlled entirely 173 | * via this parameter. 174 | * 175 | * For the purposes of DOMPDF, pixels per inch (PPI) = dots per inch (DPI). 176 | * If a size in html is given as px (or without unit as image size), 177 | * this tells the corresponding size in pt. 178 | * This adjusts the relative sizes to be similar to the rendering of the 179 | * html page in a reference browser. 180 | * 181 | * In pdf, always 1 pt = 1/72 inch 182 | * 183 | * Rendering resolution of various browsers in px per inch: 184 | * Windows Firefox and Internet Explorer: 185 | * SystemControl->Display properties->FontResolution: Default:96, largefonts:120, custom:? 186 | * Linux Firefox: 187 | * about:config *resolution: Default:96 188 | * (xorg screen dimension in mm and Desktop font dpi settings are ignored) 189 | * 190 | * Take care about extra font/image zoom factor of browser. 191 | * 192 | * In images, size in pixel attribute, img css style, are overriding 193 | * the real image dimension in px for rendering. 194 | * 195 | * @var int 196 | */ 197 | 'dpi' => 96, 198 | 199 | /** 200 | * Enable inline PHP 201 | * 202 | * If this setting is set to true then DOMPDF will automatically evaluate 203 | * inline PHP contained within tags. 204 | * 205 | * Enabling this for documents you do not trust (e.g. arbitrary remote html 206 | * pages) is a security risk. Set this option to false if you wish to process 207 | * untrusted documents. 208 | * 209 | * @var bool 210 | */ 211 | 'enable_php' => false, 212 | 213 | /** 214 | * Enable inline Javascript 215 | * 216 | * If this setting is set to true then DOMPDF will automatically insert 217 | * JavaScript code contained within tags. 218 | * 219 | * @var bool 220 | */ 221 | 'enable_javascript' => true, 222 | 223 | /** 224 | * Enable remote file access 225 | * 226 | * If this setting is set to true, DOMPDF will access remote sites for 227 | * images and CSS files as required. 228 | * This is required for part of test case www/test/image_variants.html through www/examples.php 229 | * 230 | * Attention! 231 | * This can be a security risk, in particular in combination with DOMPDF_ENABLE_PHP and 232 | * allowing remote access to dompdf.php or on allowing remote html code to be passed to 233 | * $dompdf = new DOMPDF(); $dompdf->load_html(...); 234 | * This allows anonymous users to download legally doubtful internet content which on 235 | * tracing back appears to being downloaded by your server, or allows malicious php code 236 | * in remote html pages to be executed by your server with your account privileges. 237 | * 238 | * @var bool 239 | */ 240 | 'enable_remote' => false, 241 | 242 | /** 243 | * The debug output log 244 | * @var string 245 | */ 246 | 'log_output_file' => __DIR__ . '/../../data/dompdf/log', 247 | 248 | /** 249 | * A ratio applied to the fonts height to be more like browsers' line height 250 | */ 251 | 'font_height_ratio' => 1.1, 252 | 253 | /** 254 | * Use the more-than-experimental HTML5 Lib parser 255 | */ 256 | 'enable_html5parser' => false, 257 | 'debug_png' => false, 258 | 'debug_keep_temp' => false, 259 | 'debug_css' => false, 260 | 'debug_layout' => false, 261 | 'debug_layout_lines' => false, 262 | 'debug_layout_blocks' => false, 263 | 'debug_layout_inline' => false, 264 | 'debug_layout_padding_box' => false 265 | ], 266 | 'view_manager' => [ 267 | 'strategies' => [ 268 | 'ViewPdfStrategy' 269 | ] 270 | ], 271 | 'service_manager' => [ 272 | 'shared' => [ 273 | /** 274 | * DOMPDF itself has issues rendering twice in a row so we force a 275 | * new instance to be created. 276 | */ 277 | 'DOMPDF' => false 278 | ], 279 | 'factories' => [ 280 | 'DOMPDF' => __NAMESPACE__ . '\Service\DOMPDFFactory', 281 | 'ViewPdfRenderer' => __NAMESPACE__ . '\Mvc\Service\ViewPdfRendererFactory', 282 | 'ViewPdfStrategy' => __NAMESPACE__ . '\Mvc\Service\ViewPdfStrategyFactory', 283 | ] 284 | ] 285 | ]; 286 | -------------------------------------------------------------------------------- /src/DOMPDFModule/Module.php: -------------------------------------------------------------------------------- 1 | 16 | * @copyright Copyright (c) 2012 University of Maine, 2016 Raymond J. Kolbe 17 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 18 | */ 19 | 20 | namespace DOMPDFModule; 21 | 22 | class Module 23 | { 24 | /** 25 | * @return array 26 | */ 27 | public function getConfig() 28 | { 29 | return include __DIR__ . '/../../config/module.config.php'; 30 | } 31 | 32 | public function getAutoloaderConfig() 33 | { 34 | return [ 35 | 'Zend\Loader\StandardAutoloader' => [ 36 | 'namespaces' => [ 37 | __NAMESPACE__ => __DIR__ , 38 | ] 39 | ] 40 | ]; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/DOMPDFModule/Mvc/Service/ViewPdfRendererFactory.php: -------------------------------------------------------------------------------- 1 | 16 | * @author Márcio Dias 17 | * @copyright Copyright (c) 2012 University of Maine, 2016 Raymond J. Kolbe 18 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 19 | */ 20 | 21 | namespace DOMPDFModule\Mvc\Service; 22 | 23 | use Zend\ServiceManager\FactoryInterface; 24 | use Zend\ServiceManager\ServiceLocatorInterface; 25 | use DOMPDFModule\View\Renderer\PdfRenderer; 26 | 27 | class ViewPdfRendererFactory implements FactoryInterface 28 | { 29 | /** 30 | * Create and return the PDF view renderer 31 | * 32 | * @param ServiceLocatorInterface $serviceLocator 33 | * @return PdfRenderer 34 | */ 35 | public function createService(ServiceLocatorInterface $serviceLocator) 36 | { 37 | return (new PdfRenderer()) 38 | ->setResolver($serviceLocator->get('ViewResolver')) 39 | ->setHtmlRenderer($serviceLocator->get('ViewRenderer')) 40 | ->setEngine($serviceLocator->get('dompdf')); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/DOMPDFModule/Mvc/Service/ViewPdfStrategyFactory.php: -------------------------------------------------------------------------------- 1 | 16 | * @copyright Copyright (c) 2012 University of Maine, 2016 Raymond J. Kolbe 17 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 18 | */ 19 | 20 | namespace DOMPDFModule\Mvc\Service; 21 | 22 | use Zend\ServiceManager\FactoryInterface; 23 | use Zend\ServiceManager\ServiceLocatorInterface; 24 | use DOMPDFModule\View\Strategy\PdfStrategy; 25 | 26 | class ViewPdfStrategyFactory implements FactoryInterface 27 | { 28 | /** 29 | * Create and return the PDF view strategy 30 | * 31 | * Retrieves the ViewPdfRenderer service from the service locator, and 32 | * injects it into the constructor for the PDF strategy. 33 | * 34 | * @param ServiceLocatorInterface $serviceLocator 35 | * @return PdfStrategy 36 | */ 37 | public function createService(ServiceLocatorInterface $serviceLocator) 38 | { 39 | return new PdfStrategy($serviceLocator->get('ViewPdfRenderer')); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/DOMPDFModule/Service/DOMPDFFactory.php: -------------------------------------------------------------------------------- 1 | 16 | * @copyright Copyright (c) 2012 University of Maine, 2016 Raymond J. Kolbe 17 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 18 | */ 19 | 20 | namespace DOMPDFModule\Service; 21 | 22 | use Dompdf\Dompdf; 23 | use Dompdf\Options; 24 | use Zend\ServiceManager\FactoryInterface; 25 | use Zend\ServiceManager\ServiceLocatorInterface; 26 | 27 | class DOMPDFFactory implements FactoryInterface 28 | { 29 | /** 30 | * Creates an instance of Dompdf. 31 | * 32 | * @param ServiceLocatorInterface $serviceLocator 33 | * @return Dompdf 34 | */ 35 | public function createService(ServiceLocatorInterface $serviceLocator) 36 | { 37 | $moduleConfig = $serviceLocator->get('config')['dompdf_module']; 38 | 39 | $options = [ 40 | 'temp_dir' => $moduleConfig['temporary_directory'], 41 | 'font_dir' => $moduleConfig['font_directory'], 42 | 'font_cache' => $moduleConfig['font_cache_directory'], 43 | 'chroot' => $moduleConfig['chroot'], 44 | 'log_output_file' => $moduleConfig['log_output_file'], 45 | 'default_media_type' => $moduleConfig['default_media_type'], 46 | 'default_paper_size' => $moduleConfig['default_paper_size'], 47 | 'default_font' => $moduleConfig['default_font'], 48 | 'dpi' => $moduleConfig['dpi'], 49 | 'font_height_ratio' => $moduleConfig['font_height_ratio'], 50 | 'is_php_enabled' => $moduleConfig['enable_php'], 51 | 'is_remote_enabled' => $moduleConfig['enable_remote'], 52 | 'is_javascript_enabled' => $moduleConfig['enable_javascript'], 53 | 'is_html5_parser_enabled' => $moduleConfig['enable_html5parser'], 54 | 'is_font_subsetting_enabled' => $moduleConfig['enable_fontsubsetting'], 55 | 'debug_png' => $moduleConfig['debug_png'], 56 | 'debug_keep_temp' => $moduleConfig['debug_keep_temp'], 57 | 'debug_css' => $moduleConfig['debug_css'], 58 | 'debug_layout' => $moduleConfig['debug_layout'], 59 | 'debug_layout_lines' => $moduleConfig['debug_layout_lines'], 60 | 'debug_layout_blocks' => $moduleConfig['debug_layout_blocks'], 61 | 'debug_layout_inline' => $moduleConfig['debug_layout_inline'], 62 | 'debug_layout_padding_box' => $moduleConfig['debug_layout_padding_box'], 63 | 'pdf_backend' => $moduleConfig['pdf_backend'], 64 | 'pdflib_license' => $moduleConfig['pdflib_license'] 65 | ]; 66 | 67 | return new Dompdf(new Options($options)); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/DOMPDFModule/View/Model/PdfModel.php: -------------------------------------------------------------------------------- 1 | 16 | * @copyright Copyright (c) 2012 University of Maine, 2016 Raymond J. Kolbe 17 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 18 | */ 19 | 20 | namespace DOMPDFModule\View\Model; 21 | 22 | use Zend\View\Model\ViewModel; 23 | 24 | class PdfModel extends ViewModel 25 | { 26 | const DISPLAY_INLINE = 'inline'; 27 | const DISPLAY_ATTACHMENT = 'attachment'; 28 | const DEFAULT_FILE_NAME = 'untitled.pdf'; 29 | 30 | /** 31 | * Renderer options 32 | * @var array 33 | */ 34 | protected $options = [ 35 | 'paperSize' => '8x11', 36 | 'paperOrientation' => 'portrait', 37 | 'basePath' => '/', 38 | 'fileName' => self::DEFAULT_FILE_NAME, 39 | 'display' => self::DISPLAY_INLINE 40 | ]; 41 | 42 | /** 43 | * PDF probably won't need to be captured into a 44 | * a parent container by default. 45 | * 46 | * @var string 47 | */ 48 | protected $captureTo = null; 49 | 50 | /** 51 | * PDF is usually terminal 52 | * 53 | * @var bool 54 | */ 55 | protected $terminate = true; 56 | } 57 | -------------------------------------------------------------------------------- /src/DOMPDFModule/View/Renderer/PdfRenderer.php: -------------------------------------------------------------------------------- 1 | 16 | * @copyright Copyright (c) 2012 University of Maine, 2016 Raymond J. Kolbe 17 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 18 | */ 19 | 20 | namespace DOMPDFModule\View\Renderer; 21 | 22 | use DOMPDFModule\View\Model\PdfModel; 23 | use Zend\View\Exception\InvalidArgumentException; 24 | use Zend\View\Renderer\RendererInterface as Renderer; 25 | use Zend\View\Resolver\ResolverInterface as Resolver; 26 | use Dompdf\Dompdf; 27 | 28 | class PdfRenderer implements Renderer 29 | { 30 | /** 31 | * @var Dompdf|null 32 | */ 33 | private $dompdf = null; 34 | 35 | /** 36 | * @var Resolver|null 37 | */ 38 | private $resolver = null; 39 | 40 | /** 41 | * @var Renderer|null 42 | */ 43 | private $htmlRenderer = null; 44 | 45 | /** 46 | * @param Renderer $renderer 47 | * @return $this 48 | */ 49 | public function setHtmlRenderer(Renderer $renderer) 50 | { 51 | $this->htmlRenderer = $renderer; 52 | return $this; 53 | } 54 | 55 | /** 56 | * @return Renderer 57 | */ 58 | public function getHtmlRenderer() 59 | { 60 | return $this->htmlRenderer; 61 | } 62 | 63 | /** 64 | * @param Dompdf $dompdf 65 | * @return $this 66 | */ 67 | public function setEngine(Dompdf $dompdf) 68 | { 69 | $this->dompdf = $dompdf; 70 | return $this; 71 | } 72 | 73 | /** 74 | * @return Dompdf 75 | */ 76 | public function getEngine() 77 | { 78 | return $this->dompdf; 79 | } 80 | 81 | /** 82 | * @param Resolver $resolver 83 | * @return $this 84 | */ 85 | public function setResolver(Resolver $resolver) 86 | { 87 | $this->resolver = $resolver; 88 | return $this; 89 | } 90 | 91 | /** 92 | * {@inheritdoc} 93 | */ 94 | public function render($nameOrModel, $values = null) 95 | { 96 | if (!($nameOrModel instanceof PdfModel)) { 97 | throw new InvalidArgumentException(sprintf( 98 | '%s expects a PdfModel as the first argument; received "%s"', 99 | __METHOD__, 100 | (is_object($nameOrModel) ? get_class($nameOrModel) : gettype($nameOrModel)) 101 | )); 102 | } 103 | 104 | $html = $this->getHtmlRenderer()->render($nameOrModel, $values); 105 | 106 | $paperSize = $nameOrModel->getOption('paperSize'); 107 | $paperOrientation = $nameOrModel->getOption('paperOrientation'); 108 | $basePath = $nameOrModel->getOption('basePath'); 109 | 110 | $pdf = $this->getEngine(); 111 | $pdf->setPaper($paperSize, $paperOrientation); 112 | $pdf->setBasePath($basePath); 113 | 114 | $pdf->loadHtml($html); 115 | $pdf->render(); 116 | 117 | return $pdf->output(); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /src/DOMPDFModule/View/Strategy/PdfStrategy.php: -------------------------------------------------------------------------------- 1 | 16 | * @copyright Copyright (c) 2012 University of Maine, 2016 Raymond J. Kolbe 17 | * @license http://www.opensource.org/licenses/mit-license.php MIT License 18 | */ 19 | 20 | namespace DOMPDFModule\View\Strategy; 21 | 22 | use DOMPDFModule\View\Model; 23 | use DOMPDFModule\View\Renderer\PdfRenderer; 24 | use Zend\EventManager\EventManagerInterface; 25 | use Zend\EventManager\ListenerAggregateInterface; 26 | use Zend\View\ViewEvent; 27 | 28 | class PdfStrategy implements ListenerAggregateInterface 29 | { 30 | /** 31 | * @var \Zend\Stdlib\CallbackHandler[] 32 | */ 33 | protected $listeners = []; 34 | 35 | /** 36 | * @var PdfRenderer 37 | */ 38 | protected $renderer; 39 | 40 | /** 41 | * Constructor 42 | * 43 | * @param PdfRenderer $renderer 44 | * @return void 45 | */ 46 | public function __construct(PdfRenderer $renderer) 47 | { 48 | $this->renderer = $renderer; 49 | } 50 | 51 | /** 52 | * Attach the aggregate to the specified event manager 53 | * 54 | * @param EventManagerInterface $events 55 | * @param int $priority 56 | * @return void 57 | */ 58 | public function attach(EventManagerInterface $events, $priority = 1) 59 | { 60 | $this->listeners[] = $events->attach(ViewEvent::EVENT_RENDERER, [$this, 'selectRenderer'], $priority); 61 | $this->listeners[] = $events->attach(ViewEvent::EVENT_RESPONSE, [$this, 'injectResponse'], $priority); 62 | } 63 | 64 | /** 65 | * Detach aggregate listeners from the specified event manager 66 | * 67 | * @param EventManagerInterface $events 68 | * @return void 69 | */ 70 | public function detach(EventManagerInterface $events) 71 | { 72 | foreach ($this->listeners as $index => $listener) { 73 | if ($events->detach($listener)) { 74 | unset($this->listeners[$index]); 75 | } 76 | } 77 | } 78 | 79 | /** 80 | * Detect if we should use the PdfRenderer based on model type 81 | * 82 | * @param ViewEvent $event 83 | * @return null|PdfRenderer 84 | */ 85 | public function selectRenderer(ViewEvent $event) 86 | { 87 | $model = $event->getModel(); 88 | 89 | if ($model instanceof Model\PdfModel) { 90 | return $this->renderer; 91 | } 92 | 93 | return null; 94 | } 95 | 96 | /** 97 | * Inject the response with the PDF payload and appropriate Content-Type header 98 | * 99 | * @param ViewEvent $e 100 | * @return void 101 | */ 102 | public function injectResponse(ViewEvent $event) 103 | { 104 | $renderer = $event->getRenderer(); 105 | if ($renderer !== $this->renderer) { 106 | // Discovered renderer is not ours; do nothing 107 | return; 108 | } 109 | 110 | $result = $event->getResult(); 111 | if (!is_string($result)) { 112 | // No output to display. Good bye! 113 | return; 114 | } 115 | 116 | $response = $event->getResponse(); 117 | $response->setContent($result); 118 | 119 | $model = $event->getModel(); 120 | $options = $model->getOptions(); 121 | 122 | $fileName = $options['fileName']; 123 | $dispositionType = $options['display']; 124 | 125 | if (substr($fileName, -4) != '.pdf') { 126 | $fileName .= '.pdf'; 127 | } 128 | 129 | $headerValue = sprintf('%s; filename="%s"', $dispositionType, $fileName); 130 | 131 | $response->getHeaders()->addHeaderLine('Content-Disposition', $headerValue); 132 | $response->getHeaders()->addHeaderLine('Content-Length', strlen($result)); 133 | $response->getHeaders()->addHeaderLine('Content-Type', 'application/pdf'); 134 | } 135 | } 136 | --------------------------------------------------------------------------------