[
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*]\ncharset = utf-8\nindent_size = 4\nindent_style = space\nend_of_line = lf\ninsert_final_newline = true\ntrim_trailing_whitespace = true\n\n[*.md]\ntrim_trailing_whitespace = false\n\n[*.{yml,yaml}]\nindent_size = 2\n"
  },
  {
    "path": ".gitattributes",
    "content": "* text=auto\n\n/.github         export-ignore\n/tests           export-ignore\n.editorconfig    export-ignore\n.gitattributes   export-ignore\n.gitignore       export-ignore\nchangelog.md     export-ignore\ngrumphp.yml      export-ignore\nphpstan.neon     export-ignore\nphpunit.xml.dist export-ignore\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "# These are supported funding model platforms\n\ngithub: barryvdh\ncustom: ['https://fruitcake.nl']\n\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: Bug report\nabout: Report an issue with the Dompdf wrapper\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**This is just a Dompdf wrapper!**\nI understand that this package is just a Laravel wrapper for https://github.com/dompdf/dompdf\nAny issues with PDF rendering, CSS that is not applied correctly, aligning/fonts/characters etc that are not directly related to this package, should be reported there. When having doubts, please try to reproduce the issue with just dompdf. If it's also present there, do not open an issue here please.\n\n**Describe the bug**\nA clear and concise description of what the bug is.\n\n**To Reproduce**\nSteps to reproduce the behavior:\n- Laravel and package version\n- Input HTML/CSS\n- Options / code\n\n**Expected behavior**\nA clear and concise description of what you expected to happen.\n\n**Screenshots**\nIf applicable, add screenshots to help explain your problem.\n\n**Additional context**\nAdd any other context about the problem here.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "content": "blank_issues_enabled: false\ncontact_links:\n  - name: Report CSS/HTML Bug\n    url: https://github.com/dompdf/dompdf/issues/new?title=[CSS/HTML]:%20\n    about: 'Any issues with PDF rendering are not directly related to this package, should be reported to dompdf/dompdf'\n  - name: Report FONTs/Characters/Encoding Bug\n    url: https://github.com/dompdf/dompdf/issues/new?title=[FONTs]:%20\n    about: 'Any issues with fonts rendering are not directly related to this package, should be reported to dompdf/dompdf'\n  - name: Feature request\n    url: https://github.com/dompdf/dompdf/discussions/new?category=ideas&title=[ENHANCEMENT]:%20\n    about: 'For ideas or feature requests, start a new discussion'\n  - name: Support Questions & Other\n    url: https://github.com/dompdf/dompdf/discussions/new?category=q-a&title=[SUPPORT]:%20\n    about: 'This space is only for reporting bugs. If you have a question or need help use discussions, click:'\n"
  },
  {
    "path": ".github/stale.yml",
    "content": "# Number of days of inactivity before an issue becomes stale\ndaysUntilStale: 60\n# Number of days of inactivity before a stale issue is closed\ndaysUntilClose: 7\n# Issues with these labels will never be considered stale\nexemptLabels:\n  - bug\n  - enhancement\n# Label to use when marking an issue as stale\nstaleLabel: stale\n# Comment to post when marking an issue as stale. Set to `false` to disable\nmarkComment: >\n  This issue has been automatically marked as stale because it has not had\n  recent activity. It will be closed if no further activity occurs. \n  \n  Any issues with PDF rendering itself that are not directly related to this package, \n  should be reported on https://github.com/dompdf/dompdf instead. \n  When having doubts, please try to reproduce the issue with just dompdf.\n  \n  If you believe this is an actual issue with the latest version of laravel-dompdf, \n  please reply to this issue so we can investigate further.\n  \n  Thank you for your contribution! Apologies for any delayed response on our side.\n# Comment to post when closing a stale issue. Set to `false` to disable\ncloseComment: false\n# Limit to only `issues` or `pulls`\nonly: issues\n"
  },
  {
    "path": ".github/workflows/run-static-analysis.yml",
    "content": "name: Static Analysis\n\non:\n  push:\n    branches:\n      - master\n  pull_request:\n    branches:\n      - \"*\"\n\njobs:\n  php-tests:\n    runs-on: ubuntu-latest\n\n    timeout-minutes: 15\n\n    env:\n      COMPOSER_NO_INTERACTION: 1\n\n    strategy:\n      fail-fast: false\n      matrix:\n        php: [8.1, 8.2, 8.3, 8.4, 8.5]\n        laravel: ['9.*', '10.*', '11.*', '12.*', '13.*']\n        dependency-version: [prefer-stable]\n        exclude:\n          - laravel: 12.*\n            php: 8.1\n          - laravel: 11.*\n            php: 8.1\n          - laravel: 10.*\n            php: 8.5\n          - laravel: 9.*\n            php: 8.5\n          - laravel: 13.*\n            php: 8.1\n          - laravel: 13.*\n            php: 8.2\n\n    name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.dependency-version }}\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v5\n\n      - name: Setup PHP\n        uses: shivammathur/setup-php@v2\n        with:\n          php-version: ${{ matrix.php }}\n          coverage: none\n          extensions: mbstring\n\n      - name: Install dependencies\n        run: |\n          composer remove phpro/grumphp --no-update --dev\n          composer require \"laravel/framework:${{ matrix.laravel }}\" --no-update --no-progress\n          composer update --${{ matrix.dependency-version }} --prefer-dist --no-progress\n\n      - name: Run Static Analysis\n        run: composer phpstan\n"
  },
  {
    "path": ".github/workflows/run-tests.yml",
    "content": "name: Tests\n\non:\n  push:\n    branches:\n      - master\n  pull_request:\n    branches:\n      - \"*\"\n\njobs:\n  php-tests:\n    runs-on: ubuntu-latest\n\n    timeout-minutes: 15\n\n    env:\n      COMPOSER_NO_INTERACTION: 1\n\n    strategy:\n      fail-fast: false\n      matrix:\n        php: [8.1, 8.2, 8.3, 8.4, 8.5]\n        laravel: ['9.*', '10.*', '11.*', '12.*', '13.*']\n        dependency-version: [prefer-lowest, prefer-stable]\n        exclude:\n          - laravel: 12.*\n            php: 8.1\n          - laravel: 11.*\n            php: 8.1\n          - laravel: 10.*\n            php: 8.5\n          - laravel: 9.*\n            php: 8.5\n          - laravel: 13.*\n            php: 8.1\n          - laravel: 13.*\n            php: 8.2\n\n    name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.dependency-version }}\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v5\n\n      - name: Setup PHP\n        uses: shivammathur/setup-php@v2\n        with:\n          php-version: ${{ matrix.php }}\n          coverage: none\n          extensions: mbstring\n\n      - name: Install dependencies\n        run: |\n          composer remove \"phpro/grumphp\" \"larastan/larastan\" --no-update --dev\n          composer require \"laravel/framework:${{ matrix.laravel }}\" --no-update --no-progress\n          composer update --${{ matrix.dependency-version }} --prefer-dist --no-progress\n\n      - name: Execute Unit Tests\n        run: composer test\n"
  },
  {
    "path": ".gitignore",
    "content": "/vendor\ncomposer.phar\ncomposer.lock\n.DS_Store\n/.idea\n.phpunit.cache\n.phpunit.result.cache\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Changelog\nAll notable changes to this project will be documented in this file.\n\nThe format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),\nand this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n[3.0.0]\nVersion 3.x supports DomPDF version 3.x. See the changelog in https://github.com/dompdf/dompdf/releases/tag/v3.0.0\n\nThe most notable change in laravel-dompdf are the changed defaults, to be more secure;\n - `enable_remote` is now `false` by default. Change with caution.\n - `allowedRemoteHosts` and `artifactPathValidation` are added the the config.\nAlso, support for Laravel < 9 and PHP < 8.1 is dropped.\n\n## [3.1]\nThis 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:\n\n> **Breaking Change**\n> 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.\n\nThe update for laravel-dompdf adds this to the default config, but if you have published the config, you need to add the `data://` scheme.\n\n## [3.0]\n\nVersion 3.x supports DomPDF version 3.x. See the changelog in https://github.com/dompdf/dompdf/releases/tag/v3.0.0\n\nThe most notable change in laravel-dompdf are the changed defaults, to be more secure;\n\nenable_remote is now false by default. Change with caution.\nallowedRemoteHosts and artifactPathValidation are added the the config.\nAlso, support for Laravel < 9 and PHP < 8.1 is dropped.\n\n## [2.2.0]\n### What's Changed\n* Fix setOptions by @cesarreyes3 in https://github.com/barryvdh/laravel-dompdf/pull/1040\n* Bump dompdf minimum to 2.0.7  by @barryvdh \n\n## New Contributors\n* @cesarreyes3 made their first contribution in https://github.com/barryvdh/laravel-dompdf/pull/1040\n\n**Full Changelog**: https://github.com/barryvdh/laravel-dompdf/compare/v2.1.1...v2.2.0\n\n## [2.1.1]\n### What's Changed\n* Revert \"Fix setOptions method\" by @barryvdh in https://github.com/barryvdh/laravel-dompdf/pull/1039\n\n**Full Changelog**: https://github.com/barryvdh/laravel-dompdf/compare/v2.1.0...v2.1.1\n\n## [2.1.0]\n### What's Changed\n* Convert phpunit by @barryvdh in https://github.com/barryvdh/laravel-dompdf/pull/952\n* ci: Use GitHub Actions V3 by @DannyvdSluijs in https://github.com/barryvdh/laravel-dompdf/pull/990\n* Fix named arguments when using facade by @erikn69 in https://github.com/barryvdh/laravel-dompdf/pull/1002\n* Update dompdf version as a dependancy by @AliSheikhDev in https://github.com/barryvdh/laravel-dompdf/pull/967\n* ci: Use GitHub Actions V4 by @erikn69 in https://github.com/barryvdh/laravel-dompdf/pull/1003\n* Fix phpstan analysis by @erikn69 in https://github.com/barryvdh/laravel-dompdf/pull/972\n* Fix setOptions method by @erikn69 in https://github.com/barryvdh/laravel-dompdf/pull/974\n* Small typo fix in dompdf config file by @ricklambrechts in https://github.com/barryvdh/laravel-dompdf/pull/1004\n* Upgrade to larastan/larastan by @parth391 in https://github.com/barryvdh/laravel-dompdf/pull/1014\n* Fixing \"Upgrade to larastan/larastan\" by @erikn69 in https://github.com/barryvdh/laravel-dompdf/pull/1018\n* Laravel 11 Support by @erikn69 in https://github.com/barryvdh/laravel-dompdf/pull/1036\n* Laravel 11.x Compatibility by @laravel-shift in https://github.com/barryvdh/laravel-dompdf/pull/1037\n\n### New Contributors\n* @DannyvdSluijs made their first contribution in https://github.com/barryvdh/laravel-dompdf/pull/990\n* @AliSheikhDev made their first contribution in https://github.com/barryvdh/laravel-dompdf/pull/967\n* @ricklambrechts made their first contribution in https://github.com/barryvdh/laravel-dompdf/pull/1004\n* @parth391 made their first contribution in https://github.com/barryvdh/laravel-dompdf/pull/1014\n* @laravel-shift made their first contribution in https://github.com/barryvdh/laravel-dompdf/pull/1037\n\n**Full Changelog**: https://github.com/barryvdh/laravel-dompdf/compare/v2.0.1...v2.0.2\n\n## [2.0.0]\n\nVersion 2 supports DomPDF 2.x\n\n### Changed\n- Remove the deprecated class 'Barryvdh\\DomPDF\\Facade' Facade in favor of Barryvdh\\DomPDF\\Facade\\Pdf\n- Set default Facade to Pdf instead of PDF\n- HTML5 parser option is deprecated, because this is always on.\n- `orientation` option was never used. Removed in favor of `options.default_paper_orientation`\n\n### Added\n- Upgraded to use dompdf/dompdf 2.x\n- `setOption` to change only the specified option(s), instead of replace all options. \n- Magic methods to allow calls to Dompdf methods easier. (#892)\n- `default_paper_orientation` option has been added to the defaults.\n- Add option to set public path (#890)\n\n### Deprecated\n- `setOptions` is now deprecated. Use `setOption` instead.\n- Config `dompdf.defines` has been renamed to `dompdf.options`\n\n\n## [2.0.0-beta3]\n### Changed\n- Remove the deprecated class 'Barryvdh\\DomPDF\\Facade' Facade in favor of Barryvdh\\DomPDF\\Facade\\Pdf\n- Set default Facade to Pdf instead of PDF\n\n## [2.0.0-beta2]\n\n### Added\n- Upgraded to use dompdf/dompdf 2.x\n- `setOption` to change only the specified option(s), instead of replace all options. \n- Magic methods to allow calls to Dompdf methods easier. (#892)\n- `default_paper_orientation` option has been added to the defaults.\n- Add option to set public path (#890)\n\n### Changed\n- HTML5 parser option is deprecated, because this is always on.\n- `orientation` option was never used. Removed in favor of `options.default_paper_orientation`\n\n### Deprecated\n- `setOptions` is now deprecated. Use `setOption` instead.\n- Config `dompdf.defines` has been renamed to `dompdf.options`\n\n\n## Dompdf 2.0.0, highlights since 1.2.x\n> https://github.com/dompdf/dompdf/releases/tag/v2.0.0\n> - Addresses multiple security vulnerabilities (see link)\n> - Modifies callback and page_script/page_text handling (breaking change, see link)\n> - Switches the HTML5 parser to Masterminds/HTML5\n> - Improves CSS property parsing and representation\n> - Improves border, outline, and background rendering for inline elements\n> - Switches installed fonts and font metrics cache file format to JSON\n> - Adds support for the inset CSS shorthand property and the legacy break-word keyword for word-break\n> - Adds \"end_document\" callback event\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2021 barryvdh\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "composer.json",
    "content": "{\n    \"name\": \"barryvdh/laravel-dompdf\",\n    \"description\": \"A DOMPDF Wrapper for Laravel\",\n    \"license\": \"MIT\",\n    \"keywords\": [\n        \"laravel\",\n        \"dompdf\",\n        \"pdf\"\n    ],\n    \"authors\": [\n        {\n            \"name\": \"Barry vd. Heuvel\",\n            \"email\": \"barryvdh@gmail.com\"\n        }\n    ],\n    \"require\": {\n        \"php\": \"^8.1\",\n        \"dompdf/dompdf\": \"^3.0\",\n        \"illuminate/support\": \"^9|^10|^11|^12|^13.0\"\n    },\n    \"require-dev\": {\n        \"orchestra/testbench\": \"^7|^8|^9.16|^10|^11.0\",\n        \"squizlabs/php_codesniffer\": \"^3.5\",\n        \"phpro/grumphp\": \"^2.5\",\n        \"larastan/larastan\": \"^2.7|^3.0\"\n    },\n    \"autoload\": {\n        \"psr-4\": {\n            \"Barryvdh\\\\DomPDF\\\\\": \"src\"\n        }\n    },\n    \"autoload-dev\": {\n        \"psr-4\": {\n            \"Barryvdh\\\\DomPDF\\\\Tests\\\\\": \"tests\"\n        }\n    },\n    \"extra\": {\n        \"branch-alias\": {\n            \"dev-master\": \"3.0-dev\"\n        },\n        \"laravel\": {\n            \"providers\": [\n                \"Barryvdh\\\\DomPDF\\\\ServiceProvider\"\n            ],\n            \"aliases\": {\n                \"Pdf\": \"Barryvdh\\\\DomPDF\\\\Facade\\\\Pdf\",\n                \"PDF\": \"Barryvdh\\\\DomPDF\\\\Facade\\\\Pdf\"\n            }\n        }\n    },\n    \"scripts\": {\n        \"test\": \"phpunit\",\n        \"check-style\": \"phpcs -p --standard=psr12 src/\",\n        \"fix-style\": \"phpcbf -p --standard=psr12 src/\",\n        \"phpstan\": \"phpstan analyze --memory-limit=-1\"\n    },\n    \"minimum-stability\": \"dev\",\n    \"prefer-stable\": true,\n    \"config\": {\n        \"allow-plugins\": {\n            \"phpro/grumphp\": true\n        }\n    }\n}\n"
  },
  {
    "path": "config/dompdf.php",
    "content": "<?php\n\nreturn [\n\n    /*\n    |--------------------------------------------------------------------------\n    | Settings\n    |--------------------------------------------------------------------------\n    |\n    | Set some default values. It is possible to add all defines that can be set\n    | in dompdf_config.inc.php. You can also override the entire config file.\n    |\n    */\n    'show_warnings' => false,   // Throw an Exception on warnings from dompdf\n\n    'public_path' => null,  // Override the public path if needed\n\n    /*\n     * Dejavu Sans font is missing glyphs for converted entities, turn it off if you need to show € and £.\n     */\n    'convert_entities' => true,\n\n    'options' => [\n        /**\n         * The location of the DOMPDF font directory\n         *\n         * The location of the directory where DOMPDF will store fonts and font metrics\n         * Note: This directory must exist and be writable by the webserver process.\n         * *Please note the trailing slash.*\n         *\n         * Notes regarding fonts:\n         * Additional .afm font metrics can be added by executing load_font.php from command line.\n         *\n         * Only the original \"Base 14 fonts\" are present on all pdf viewers. Additional fonts must\n         * be embedded in the pdf file or the PDF may not display correctly. This can significantly\n         * increase file size unless font subsetting is enabled. Before embedding a font please\n         * review your rights under the font license.\n         *\n         * Any font specification in the source HTML is translated to the closest font available\n         * in the font directory.\n         *\n         * The pdf standard \"Base 14 fonts\" are:\n         * Courier, Courier-Bold, Courier-BoldOblique, Courier-Oblique,\n         * Helvetica, Helvetica-Bold, Helvetica-BoldOblique, Helvetica-Oblique,\n         * Times-Roman, Times-Bold, Times-BoldItalic, Times-Italic,\n         * Symbol, ZapfDingbats.\n         */\n        'font_dir' => storage_path('fonts'), // advised by dompdf (https://github.com/dompdf/dompdf/pull/782)\n\n        /**\n         * The location of the DOMPDF font cache directory\n         *\n         * This directory contains the cached font metrics for the fonts used by DOMPDF.\n         * This directory can be the same as DOMPDF_FONT_DIR\n         *\n         * Note: This directory must exist and be writable by the webserver process.\n         */\n        'font_cache' => storage_path('fonts'),\n\n        /**\n         * The location of a temporary directory.\n         *\n         * The directory specified must be writeable by the webserver process.\n         * The temporary directory is required to download remote images and when\n         * using the PDFLib back end.\n         */\n        'temp_dir' => sys_get_temp_dir(),\n\n        /**\n         * ==== IMPORTANT ====\n         *\n         * dompdf's \"chroot\": Prevents dompdf from accessing system files or other\n         * files on the webserver.  All local files opened by dompdf must be in a\n         * subdirectory of this directory.  DO NOT set it to '/' since this could\n         * allow an attacker to use dompdf to read any files on the server.  This\n         * should be an absolute path.\n         * This is only checked on command line call by dompdf.php, but not by\n         * direct class use like:\n         * $dompdf = new DOMPDF();  $dompdf->load_html($htmldata); $dompdf->render(); $pdfdata = $dompdf->output();\n         */\n        'chroot' => realpath(base_path()),\n\n        /**\n         * Protocol whitelist\n         *\n         * Protocols and PHP wrappers allowed in URIs, and the validation rules\n         * that determine if a resouce may be loaded. Full support is not guaranteed\n         * for the protocols/wrappers specified\n         * by this array.\n         *\n         * @var array\n         */\n        'allowed_protocols' => [\n            'data://' => ['rules' => []],\n            'file://' => ['rules' => []],\n            'http://' => ['rules' => []],\n            'https://' => ['rules' => []],\n        ],\n\n        /**\n         * Operational artifact (log files, temporary files) path validation\n         */\n        'artifactPathValidation' => null,\n\n        /**\n         * @var string\n         */\n        'log_output_file' => null,\n\n        /**\n         * Whether to enable font subsetting or not.\n         */\n        'enable_font_subsetting' => false,\n\n        /**\n         * The PDF rendering backend to use\n         *\n         * Valid settings are 'PDFLib', 'CPDF' (the bundled R&OS PDF class), 'GD' and\n         * 'auto'. 'auto' will look for PDFLib and use it if found, or if not it will\n         * fall back on CPDF. 'GD' renders PDFs to graphic files.\n         * {@link * Canvas_Factory} ultimately determines which rendering class to\n         * instantiate based on this setting.\n         *\n         * Both PDFLib & CPDF rendering backends provide sufficient rendering\n         * capabilities for dompdf, however additional features (e.g. object,\n         * image and font support, etc.) differ between backends.  Please see\n         * {@link PDFLib_Adapter} for more information on the PDFLib backend\n         * and {@link CPDF_Adapter} and lib/class.pdf.php for more information\n         * on CPDF. Also see the documentation for each backend at the links\n         * below.\n         *\n         * The GD rendering backend is a little different than PDFLib and\n         * CPDF. Several features of CPDF and PDFLib are not supported or do\n         * not make any sense when creating image files.  For example,\n         * multiple pages are not supported, nor are PDF 'objects'.  Have a\n         * look at {@link GD_Adapter} for more information.  GD support is\n         * experimental, so use it at your own risk.\n         *\n         * @link http://www.pdflib.com\n         * @link http://www.ros.co.nz/pdf\n         * @link http://www.php.net/image\n         */\n        'pdf_backend' => 'CPDF',\n\n        /**\n         * html target media view which should be rendered into pdf.\n         * List of types and parsing rules for future extensions:\n         * http://www.w3.org/TR/REC-html40/types.html\n         *   screen, tty, tv, projection, handheld, print, braille, aural, all\n         * Note: aural is deprecated in CSS 2.1 because it is replaced by speech in CSS 3.\n         * Note, even though the generated pdf file is intended for print output,\n         * the desired content might be different (e.g. screen or projection view of html file).\n         * Therefore allow specification of content here.\n         */\n        'default_media_type' => 'screen',\n\n        /**\n         * The default paper size.\n         *\n         * North America standard is \"letter\"; other countries generally \"a4\"\n         *\n         * @see CPDF_Adapter::PAPER_SIZES for valid sizes ('letter', 'legal', 'A4', etc.)\n         */\n        'default_paper_size' => 'a4',\n\n        /**\n         * The default paper orientation.\n         *\n         * The orientation of the page (portrait or landscape).\n         *\n         * @var string\n         */\n        'default_paper_orientation' => 'portrait',\n\n        /**\n         * The default font family\n         *\n         * Used if no suitable fonts can be found. This must exist in the font folder.\n         *\n         * @var string\n         */\n        'default_font' => 'serif',\n\n        /**\n         * Image DPI setting\n         *\n         * This setting determines the default DPI setting for images and fonts.  The\n         * DPI may be overridden for inline images by explictly setting the\n         * image's width & height style attributes (i.e. if the image's native\n         * width is 600 pixels and you specify the image's width as 72 points,\n         * the image will have a DPI of 600 in the rendered PDF.  The DPI of\n         * background images can not be overridden and is controlled entirely\n         * via this parameter.\n         *\n         * For the purposes of DOMPDF, pixels per inch (PPI) = dots per inch (DPI).\n         * If a size in html is given as px (or without unit as image size),\n         * this tells the corresponding size in pt.\n         * This adjusts the relative sizes to be similar to the rendering of the\n         * html page in a reference browser.\n         *\n         * In pdf, always 1 pt = 1/72 inch\n         *\n         * Rendering resolution of various browsers in px per inch:\n         * Windows Firefox and Internet Explorer:\n         *   SystemControl->Display properties->FontResolution: Default:96, largefonts:120, custom:?\n         * Linux Firefox:\n         *   about:config *resolution: Default:96\n         *   (xorg screen dimension in mm and Desktop font dpi settings are ignored)\n         *\n         * Take care about extra font/image zoom factor of browser.\n         *\n         * In images, <img> size in pixel attribute, img css style, are overriding\n         * the real image dimension in px for rendering.\n         *\n         * @var int\n         */\n        'dpi' => 96,\n\n        /**\n         * Enable embedded PHP\n         *\n         * If this setting is set to true then DOMPDF will automatically evaluate embedded PHP contained\n         * within <script type=\"text/php\"> ... </script> tags.\n         *\n         * ==== IMPORTANT ==== Enabling this for documents you do not trust (e.g. arbitrary remote html pages)\n         * is a security risk.\n         * Embedded scripts are run with the same level of system access available to dompdf.\n         * Set this option to false (recommended) if you wish to process untrusted documents.\n         * This setting may increase the risk of system exploit.\n         * Do not change this settings without understanding the consequences.\n         * Additional documentation is available on the dompdf wiki at:\n         * https://github.com/dompdf/dompdf/wiki\n         *\n         * @var bool\n         */\n        'enable_php' => false,\n\n        /**\n         * Enable inline JavaScript\n         *\n         * If this setting is set to true then DOMPDF will automatically insert JavaScript code contained\n         * within <script type=\"text/javascript\"> ... </script> tags as written into the PDF.\n         * NOTE: This is PDF-based JavaScript to be executed by the PDF viewer,\n         * not browser-based JavaScript executed by Dompdf.\n         *\n         * @var bool\n         */\n        'enable_javascript' => true,\n\n        /**\n         * Enable remote file access\n         *\n         *  If this setting is set to true, DOMPDF will access remote sites for\n         *  images and CSS files as required.\n         *\n         *  ==== IMPORTANT ====\n         *  This can be a security risk, in particular in combination with isPhpEnabled and\n         *  allowing remote html code to be passed to $dompdf = new DOMPDF(); $dompdf->load_html(...);\n         *  This allows anonymous users to download legally doubtful internet content which on\n         *  tracing back appears to being downloaded by your server, or allows malicious php code\n         *  in remote html pages to be executed by your server with your account privileges.\n         *\n         *  This setting may increase the risk of system exploit. Do not change\n         *  this settings without understanding the consequences. Additional\n         *  documentation is available on the dompdf wiki at:\n         *  https://github.com/dompdf/dompdf/wiki\n         *\n         * @var bool\n         */\n        'enable_remote' => false,\n\n        /**\n         * List of allowed remote hosts\n         *\n         * Each value of the array must be a valid hostname.\n         *\n         * This will be used to filter which resources can be loaded in combination with\n         * isRemoteEnabled. If enable_remote is FALSE, then this will have no effect.\n         *\n         * Leave to NULL to allow any remote host.\n         *\n         * @var array|null\n         */\n        'allowed_remote_hosts' => null,\n\n        /**\n         * A ratio applied to the fonts height to be more like browsers' line height\n         */\n        'font_height_ratio' => 1.1,\n\n        /**\n         * Use the HTML5 Lib parser\n         *\n         * @deprecated This feature is now always on in dompdf 2.x\n         *\n         * @var bool\n         */\n        'enable_html5_parser' => true,\n    ],\n\n];\n"
  },
  {
    "path": "grumphp.yml",
    "content": "grumphp:\n    tasks:\n        phpunit:\n            config_file: ~\n            testsuite: ~\n            group: []\n            always_execute: false\n        phpcs:\n            standard: PSR12\n            warning_severity: ~\n            ignore_patterns:\n            - tests/\n            triggered_by: [php]\n        phpstan:\n            autoload_file: ~\n            configuration: ~\n            level: null\n            force_patterns: [ ]\n            ignore_patterns: [ ]\n            triggered_by: [ 'php' ]\n            memory_limit: \"-1\"\n            use_grumphp_paths: true\n"
  },
  {
    "path": "phpstan.neon",
    "content": "includes:\n    - vendor/larastan/larastan/extension.neon\n\nparameters:\n    reportUnmatchedIgnoredErrors: false\n    paths:\n        - src\n        - tests\n    level: 8\n    ignoreErrors:\n        # This is a global alias that cannot be detected by Larastan.\n        - '#Call to static method loadHTML\\(\\) on an unknown class PDF\\.#'\n        - '#Call to static method loadHTML\\(\\) on an unknown class Pdf\\.#'\n"
  },
  {
    "path": "phpunit.xml.dist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<phpunit xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" backupGlobals=\"false\" bootstrap=\"vendor/autoload.php\" colors=\"true\" processIsolation=\"false\" stopOnError=\"false\" stopOnFailure=\"false\" xsi:noNamespaceSchemaLocation=\"https://schema.phpunit.de/10.0/phpunit.xsd\" cacheDirectory=\".phpunit.cache\" backupStaticProperties=\"false\">\n  <coverage>\n    <include>\n      <directory>./src</directory>\n    </include>\n  </coverage>\n  <testsuites>\n    <testsuite name=\"Test Suite\">\n      <directory>./tests/</directory>\n    </testsuite>\n  </testsuites>\n</phpunit>\n"
  },
  {
    "path": "readme.md",
    "content": "## DOMPDF Wrapper for Laravel\n\n### Laravel wrapper for [Dompdf HTML to PDF Converter](https://github.com/dompdf/dompdf)\n\n[![Tests](https://github.com/barryvdh/laravel-dompdf/workflows/Tests/badge.svg)](https://github.com/barryvdh/laravel-dompdf/actions)\n[![Packagist License](https://img.shields.io/badge/Licence-MIT-blue)](http://choosealicense.com/licenses/mit/)\n[![Latest Stable Version](https://img.shields.io/packagist/v/barryvdh/laravel-dompdf?label=Stable)](https://packagist.org/packages/barryvdh/laravel-dompdf)\n[![Total Downloads](https://img.shields.io/packagist/dt/barryvdh/laravel-dompdf.svg?label=Downloads)](https://packagist.org/packages/barryvdh/laravel-dompdf)\n[![Fruitcake](https://img.shields.io/badge/Powered%20By-Fruitcake-b2bc35.svg)](https://fruitcake.nl/)\n\n## Installation\n\n### Laravel\nRequire this package in your composer.json and update composer. This will download the package and the dompdf + fontlib libraries also.\n\n    composer require barryvdh/laravel-dompdf\n\n### Lumen\n\nAfter updating composer add the following lines to register provider in `bootstrap/app.php`\n\n  ```\n  $app->register(\\Barryvdh\\DomPDF\\ServiceProvider::class);\n  ```\n  \nTo change the configuration, copy the config file to your config folder and enable it in `bootstrap/app.php`:\n\n  ```\n  $app->configure('dompdf');\n  ```\n  \n## Using\n\nYou 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.\n\n```php\n    use Barryvdh\\DomPDF\\Facade\\Pdf;\n\n    $pdf = Pdf::loadView('pdf.invoice', $data);\n    return $pdf->download('invoice.pdf');\n```\n\nor use the App container:\n\n```php\n    $pdf = App::make('dompdf.wrapper');\n    $pdf->loadHTML('<h1>Test</h1>');\n    return $pdf->stream();\n```\n\nOr use the facade:\n\nYou can chain the methods:\n\n```php\n    return Pdf::loadFile(public_path().'/myfile.html')->save('/path-to/my_stored_file.pdf')->stream('download.pdf');\n```\n\nYou can change the orientation and paper size, and hide or show errors (by default, errors are shown when debug is on)\n\n```php\n    Pdf::loadHTML($html)->setPaper('a4', 'landscape')->setWarnings(false)->save('myfile.pdf')\n```\n\nIf you need the output as a string, you can get the rendered PDF with the output() function, so you can save/output it yourself.\n\nUse `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).\nYou can also use your ConfigProvider to set certain keys.\n\n### Configuration\nThe 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:\n```shell\n    php artisan vendor:publish --provider=\"Barryvdh\\DomPDF\\ServiceProvider\"\n```\n\nYou can still alter the dompdf options in your code before generating the pdf using this command:\n```php\n    Pdf::setOption(['dpi' => 150, 'defaultFont' => 'sans-serif']);\n```\n    \nAvailable options and their defaults:\n* __rootDir__: \"{app_directory}/vendor/dompdf/dompdf\"\n* __tempDir__: \"/tmp\" _(available in config/dompdf.php)_\n* __fontDir__: \"{app_directory}/storage/fonts\" _(available in config/dompdf.php)_\n* __fontCache__: \"{app_directory}/storage/fonts\" _(available in config/dompdf.php)_\n* __chroot__: \"{app_directory}\" _(available in config/dompdf.php)_\n* __logOutputFile__: \"/tmp/log.htm\"\n* __defaultMediaType__: \"screen\" _(available in config/dompdf.php)_\n* __defaultPaperSize__: \"a4\" _(available in config/dompdf.php)_\n* __defaultFont__: \"serif\" _(available in config/dompdf.php)_\n* __dpi__: 96 _(available in config/dompdf.php)_\n* __fontHeightRatio__: 1.1 _(available in config/dompdf.php)_\n* __isPhpEnabled__: false _(available in config/dompdf.php)_\n* __isRemoteEnabled__: false _(available in config/dompdf.php)_\n* __isJavascriptEnabled__: true _(available in config/dompdf.php)_\n* __isHtml5ParserEnabled__: true _(available in config/dompdf.php)_\n* __allowedRemoteHosts__: null _(available in config/dompdf.php)_\n* __isFontSubsettingEnabled__: false _(available in config/dompdf.php)_\n* __debugPng__: false\n* __debugKeepTemp__: false\n* __debugCss__: false\n* __debugLayout__: false\n* __debugLayoutLines__: true\n* __debugLayoutBlocks__: true\n* __debugLayoutInline__: true\n* __debugLayoutPaddingBox__: true\n* __pdfBackend__: \"CPDF\" _(available in config/dompdf.php)_\n* __pdflibLicense__: \"\"\n* __adminUsername__: \"user\"\n* __adminPassword__: \"password\"\n* __artifactPathValidation__: null _(available in config/dompdf.php)_\n\n#### Note: Since 3.x the remote access is disabled by default, to provide more security. Use with caution!\n\n### Tip: UTF-8 support\nIn your templates, set the UTF-8 Metatag:\n\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/>\n\n### Tip: Page breaks\nYou can use the CSS `page-break-before`/`page-break-after` properties to create a new page.\n\n    <style>\n    .page-break {\n        page-break-after: always;\n    }\n    </style>\n    <h1>Page 1</h1>\n    <div class=\"page-break\"></div>\n    <h1>Page 2</h1>\n    \n### License\n\nThis DOMPDF Wrapper for Laravel is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT)\n"
  },
  {
    "path": "src/Facade/Pdf.php",
    "content": "<?php\n\nnamespace Barryvdh\\DomPDF\\Facade;\n\nuse Barryvdh\\DomPDF\\PDF as BasePDF;\nuse Illuminate\\Support\\Facades\\Facade as IlluminateFacade;\nuse RuntimeException;\n\n/**\n * @method static BasePDF setBaseHost(string $baseHost)\n * @method static BasePDF setBasePath(string $basePath)\n * @method static BasePDF setCanvas(\\Dompdf\\Canvas $canvas)\n * @method static BasePDF setCallbacks(array<string, mixed> $callbacks)\n * @method static BasePDF setCss(\\Dompdf\\Css\\Stylesheet $css)\n * @method static BasePDF setDefaultView(string $defaultView, array<string, mixed> $options)\n * @method static BasePDF setDom(\\DOMDocument $dom)\n * @method static BasePDF setFontMetrics(\\Dompdf\\FontMetrics $fontMetrics)\n * @method static BasePDF setHttpContext(resource|array<string, mixed> $httpContext)\n * @method static BasePDF setPaper(string|float[] $paper, string $orientation = 'portrait')\n * @method static BasePDF setProtocol(string $protocol)\n * @method static BasePDF setTree(\\Dompdf\\Frame\\FrameTree $tree)\n * @method static BasePDF setWarnings(bool $warnings)\n * @method static BasePDF setOption(array<string, mixed>|string $attribute, $value = null)\n * @method static BasePDF setOptions(array<string, mixed> $options)\n * @method static BasePDF loadView(string $view, array<string, mixed> $data = [], array<string, mixed> $mergeData = [], ?string $encoding = null)\n * @method static BasePDF loadHTML(string $string, ?string $encoding = null)\n * @method static BasePDF loadFile(string $file)\n * @method static BasePDF addInfo(array<string, string> $info)\n * @method static string output(array<string, int> $options = [])\n * @method static BasePDF save()\n * @method static \\Illuminate\\Http\\Response download(string $filename = 'document.pdf')\n * @method static \\Illuminate\\Http\\Response stream(string $filename = 'document.pdf')\n */\nclass Pdf extends IlluminateFacade\n{\n    /**\n     * Get the registered name of the component.\n     *\n     * @return string\n     */\n    protected static function getFacadeAccessor()\n    {\n        return 'dompdf.wrapper';\n    }\n\n    /**\n     * Handle dynamic, static calls to the object.\n     *\n     * @param string $method\n     * @param array<mixed> $args\n     * @return mixed\n     *\n     * @throws \\RuntimeException\n     */\n    public static function __callStatic($method, $args)\n    {\n        /** @var \\Illuminate\\Contracts\\Foundation\\Application|null */\n        $app = static::getFacadeApplication();\n        if (! $app) {\n            throw new RuntimeException('Facade application has not been set.');\n        }\n\n        // Resolve a new instance, avoid using a cached instance\n        $instance = $app->make(static::getFacadeAccessor());\n\n        return $instance->$method(...$args);\n    }\n}\n"
  },
  {
    "path": "src/PDF.php",
    "content": "<?php\n\nnamespace Barryvdh\\DomPDF;\n\nuse Dompdf\\Adapter\\CPDF;\nuse Dompdf\\Dompdf;\nuse Dompdf\\Options;\nuse Exception;\nuse Illuminate\\Filesystem\\Filesystem;\nuse Illuminate\\Contracts\\View\\Factory as ViewFactory;\nuse Illuminate\\Contracts\\Config\\Repository as ConfigRepository;\nuse Illuminate\\Http\\Response;\nuse Illuminate\\Support\\Facades\\Storage;\nuse Illuminate\\Support\\Str;\nuse Symfony\\Component\\HttpFoundation\\HeaderUtils;\n\n/**\n * A Laravel wrapper for Dompdf\n *\n * @package laravel-dompdf\n * @author Barry vd. Heuvel\n *\n * @method PDF setBaseHost(string $baseHost)\n * @method PDF setBasePath(string $basePath)\n * @method PDF setCanvas(\\Dompdf\\Canvas $canvas)\n * @method PDF setCallbacks(array<string, mixed> $callbacks)\n * @method PDF setCss(\\Dompdf\\Css\\Stylesheet $css)\n * @method PDF setDefaultView(string $defaultView, array<string, mixed> $options)\n * @method PDF setDom(\\DOMDocument $dom)\n * @method PDF setFontMetrics(\\Dompdf\\FontMetrics $fontMetrics)\n * @method PDF setHttpContext(resource|array<string, mixed> $httpContext)\n * @method PDF setPaper(string|float[] $paper, string $orientation = 'portrait')\n * @method PDF setProtocol(string $protocol)\n * @method PDF setTree(\\Dompdf\\Frame\\FrameTree $tree)\n * @method string getBaseHost()\n * @method string getBasePath()\n * @method \\Dompdf\\Canvas getCanvas()\n * @method array<string, mixed> getCallbacks()\n * @method \\Dompdf\\Css\\Stylesheet getCss()\n * @method \\DOMDocument getDom()\n * @method \\Dompdf\\FontMetrics getFontMetrics()\n * @method resource getHttpContext()\n * @method Options getOptions()\n * @method \\Dompdf\\Frame\\FrameTree getTree()\n * @method string getPaperOrientation()\n * @method float[] getPaperSize()\n * @method string getProtocol()\n */\nclass PDF\n{\n    /** @var Dompdf  */\n    protected $dompdf;\n\n    /** @var \\Illuminate\\Contracts\\Config\\Repository  */\n    protected $config;\n\n    /** @var \\Illuminate\\Filesystem\\Filesystem  */\n    protected $files;\n\n    /** @var \\Illuminate\\Contracts\\View\\Factory  */\n    protected $view;\n\n    /** @var bool */\n    protected $rendered = false;\n\n    /** @var bool */\n    protected $showWarnings;\n\n    /** @var string */\n    protected $public_path;\n\n    public function __construct(Dompdf $dompdf, ConfigRepository $config, Filesystem $files, ViewFactory $view)\n    {\n        $this->dompdf = $dompdf;\n        $this->config = $config;\n        $this->files = $files;\n        $this->view = $view;\n\n        $this->showWarnings = $this->config->get('dompdf.show_warnings', false);\n    }\n\n    /**\n     * Get the DomPDF instance\n     */\n    public function getDomPDF(): Dompdf\n    {\n        return $this->dompdf;\n    }\n\n    /**\n     * Show or hide warnings\n     */\n    public function setWarnings(bool $warnings): self\n    {\n        $this->showWarnings = $warnings;\n        return $this;\n    }\n\n    /**\n     * Load a HTML string\n     *\n     * @param string|null $encoding Not used yet\n     */\n    public function loadHTML(string $string, ?string $encoding = null): self\n    {\n        $string = $this->convertEntities($string);\n        $this->dompdf->loadHtml($string, $encoding);\n        $this->rendered = false;\n        return $this;\n    }\n\n    /**\n     * Load a HTML file\n     */\n    public function loadFile(string $file): self\n    {\n        $this->dompdf->loadHtmlFile($file);\n        $this->rendered = false;\n        return $this;\n    }\n\n    /**\n     * Add metadata info\n     * @param array<string, string> $info\n     */\n    public function addInfo(array $info): self\n    {\n        foreach ($info as $name => $value) {\n            $this->dompdf->add_info($name, $value);\n        }\n        return $this;\n    }\n\n    /**\n     * Load a View and convert to HTML\n     * @param array<string, mixed> $data\n     * @param array<string, mixed> $mergeData\n     * @param string|null $encoding Not used yet\n     */\n    public function loadView(string $view, array $data = [], array $mergeData = [], ?string $encoding = null): self\n    {\n        $html = $this->view->make($view, $data, $mergeData)->render();\n        return $this->loadHTML($html, $encoding);\n    }\n\n    /**\n     * Set/Change an option (or array of options) in Dompdf\n     *\n     * @param array<string, mixed>|string $attribute\n     * @param null|mixed $value\n     */\n    public function setOption($attribute, $value = null): self\n    {\n        $this->dompdf->getOptions()->set($attribute, $value);\n        return $this;\n    }\n\n    /**\n     * Replace all the Options from DomPDF\n     *\n     * @param array<string, mixed> $options\n     */\n    public function setOptions(array $options, bool $mergeWithDefaults = false): self\n    {\n        if ($mergeWithDefaults) {\n            $options = array_merge(app()->make('dompdf.options'), $options);\n        }\n\n        $this->dompdf->setOptions(new Options($options));\n        return $this;\n    }\n\n    /**\n     * Output the PDF as a string.\n     *\n     * The options parameter controls the output. Accepted options are:\n     *\n     * 'compress' = > 1 or 0 - apply content stream compression, this is\n     *    on (1) by default\n     *\n     * @param array<string, int> $options\n     *\n     * @return string The rendered PDF as string\n     */\n    public function output(array $options = []): string\n    {\n        if (!$this->rendered) {\n            $this->render();\n        }\n        return (string) $this->dompdf->output($options);\n    }\n\n    /**\n     * Save the PDF to a file\n     */\n    public function save(string $filename, ?string $disk = null): self\n    {\n        $disk = $disk ?: $this->config->get('dompdf.disk');\n\n        if (! is_null($disk)) {\n            Storage::disk($disk)->put($filename, $this->output());\n            return $this;\n        }\n\n        $this->files->put($filename, $this->output());\n        return $this;\n    }\n\n    /**\n     * Make the PDF downloadable by the user\n     */\n    public function download(string $filename = 'document.pdf'): Response\n    {\n        $output = $this->output();\n        $fallback = $this->fallbackName($filename);\n\n        return new Response($output, 200, [\n            'Content-Type' => 'application/pdf',\n            'Content-Disposition' => HeaderUtils::makeDisposition('attachment', $filename, $fallback),\n            'Content-Length' => strlen($output),\n        ]);\n    }\n\n    /**\n     * Return a response with the PDF to show in the browser\n     */\n    public function stream(string $filename = 'document.pdf'): Response\n    {\n        $output = $this->output();\n        $fallback = $this->fallbackName($filename);\n\n\n        return new Response($output, 200, [\n            'Content-Type' => 'application/pdf',\n            'Content-Disposition' => HeaderUtils::makeDisposition('inline', $filename, $fallback),\n        ]);\n    }\n\n    /**\n     * Render the PDF\n     */\n    public function render(): void\n    {\n        $this->dompdf->render();\n\n        if ($this->showWarnings) {\n            global $_dompdf_warnings;\n            if (!empty($_dompdf_warnings) && count($_dompdf_warnings)) {\n                $warnings = '';\n                foreach ($_dompdf_warnings as $msg) {\n                    $warnings .= $msg . \"\\n\";\n                }\n                // $warnings .= $this->dompdf->get_canvas()->get_cpdf()->messages;\n                if (!empty($warnings)) {\n                    throw new Exception($warnings);\n                }\n            }\n        }\n        $this->rendered = true;\n    }\n\n    /** @param array<string> $pc */\n    public function setEncryption(string $password, string $ownerpassword = '', array $pc = []): void\n    {\n        $this->render();\n        $canvas = $this->dompdf->getCanvas();\n        if (! $canvas instanceof CPDF) {\n            throw new \\RuntimeException('Encryption is only supported when using CPDF');\n        }\n        $canvas->get_cpdf()->setEncryption($password, $ownerpassword, $pc);\n    }\n\n    protected function convertEntities(string $subject): string\n    {\n        if (false === $this->config->get('dompdf.convert_entities', true)) {\n            return $subject;\n        }\n\n        $entities = [\n            '€' => '&euro;',\n            '£' => '&pound;',\n        ];\n\n        foreach ($entities as $search => $replace) {\n            $subject = str_replace($search, $replace, $subject);\n        }\n        return $subject;\n    }\n\n    /**\n     * Dynamically handle calls into the dompdf instance.\n     *\n     * @param string $method\n     * @param array<mixed> $parameters\n     * @return $this|mixed\n     */\n    public function __call($method, $parameters)\n    {\n        if (method_exists($this, $method)) {\n            return $this->$method(...$parameters);\n        }\n\n        if (method_exists($this->dompdf, $method)) {\n            $return = $this->dompdf->$method(...$parameters);\n\n            return $return == $this->dompdf ? $this : $return;\n        }\n\n        throw new \\UnexpectedValueException(\"Method [{$method}] does not exist on PDF instance.\");\n    }\n\n    /**\n     * Make a safe fallback filename\n     */\n    protected function fallbackName(string $filename): string\n    {\n        return str_replace('%', '', Str::ascii($filename));\n    }\n}\n"
  },
  {
    "path": "src/ServiceProvider.php",
    "content": "<?php\n\nnamespace Barryvdh\\DomPDF;\n\nuse Dompdf\\Dompdf;\nuse Exception;\nuse Illuminate\\Support\\Str;\nuse Illuminate\\Support\\ServiceProvider as IlluminateServiceProvider;\n\nclass ServiceProvider extends IlluminateServiceProvider\n{\n    /**\n     * Indicates if loading of the provider is deferred.\n     *\n     * @var bool\n     */\n    protected $defer = false;\n\n    /**\n     * Register the service provider.\n     *\n     * @throws \\Exception\n     * @return void\n     */\n    public function register(): void\n    {\n        $configPath = __DIR__ . '/../config/dompdf.php';\n        $this->mergeConfigFrom($configPath, 'dompdf');\n\n        $this->app->bind('dompdf.options', function ($app) {\n            $defines = $app['config']->get('dompdf.defines');\n\n            if ($defines) {\n                $options = [];\n                /**\n                 * @var string $key\n                 * @var mixed $value\n                 */\n                foreach ($defines as $key => $value) {\n                    $key = strtolower(str_replace('DOMPDF_', '', $key));\n                    $options[$key] = $value;\n                }\n            } else {\n                $options = $app['config']->get('dompdf.options');\n            }\n\n            return $options;\n        });\n\n        $this->app->bind('dompdf', function ($app) {\n\n            $options = $app->make('dompdf.options');\n            $dompdf = new Dompdf($options);\n            $path = realpath($app['config']->get('dompdf.public_path') ?: base_path('public'));\n            if ($path === false) {\n                throw new \\RuntimeException('Cannot resolve public path');\n            }\n            $dompdf->setBasePath($path);\n\n            return $dompdf;\n        });\n        $this->app->alias('dompdf', Dompdf::class);\n\n        $this->app->bind('dompdf.wrapper', function ($app) {\n            return new PDF($app['dompdf'], $app['config'], $app['files'], $app['view']);\n        });\n    }\n\n    /**\n     * Check if package is running under Lumen app\n     */\n    protected function isLumen(): bool\n    {\n        return Str::contains($this->app->version(), 'Lumen') === true;\n    }\n\n    public function boot(): void\n    {\n        if (! $this->isLumen()) {\n            $configPath = __DIR__ . '/../config/dompdf.php';\n            $this->publishes([$configPath => config_path('dompdf.php')], 'config');\n        }\n    }\n\n    /**\n     * Get the services provided by the provider.\n     *\n     * @return array<string>\n     */\n    public function provides(): array\n    {\n        return ['dompdf', 'dompdf.options', 'dompdf.wrapper'];\n    }\n}\n"
  },
  {
    "path": "tests/PdfTest.php",
    "content": "<?php\n\nnamespace Barryvdh\\DomPDF\\Tests;\n\nuse Barryvdh\\DomPDF\\Facade;\nuse Illuminate\\Http\\Response;\nuse Illuminate\\Support\\Facades\\Storage;\n\nclass PdfTest extends TestCase\n{\n    public function testAlias(): void\n    {\n        $pdf = \\Pdf::loadHTML('<h1>Test</h1>');\n        /** @var Response $response */\n        $response = $pdf->download('test.pdf');\n\n        $this->assertInstanceOf(Response::class, $response);\n        $this->assertNotEmpty($response->getContent());\n        $this->assertEquals('application/pdf', $response->headers->get('Content-Type'));\n        $this->assertEquals('attachment; filename=test.pdf', $response->headers->get('Content-Disposition'));\n    }\n\n    public function testAliasCaps(): void\n    {\n        $pdf = \\PDF::loadHTML('<h1>Test</h1>');\n        /** @var Response $response */\n        $response = $pdf->download('test.pdf');\n\n        $this->assertInstanceOf(Response::class, $response);\n        $this->assertNotEmpty($response->getContent());\n        $this->assertEquals('application/pdf', $response->headers->get('Content-Type'));\n        $this->assertEquals('attachment; filename=test.pdf', $response->headers->get('Content-Disposition'));\n    }\n\n    public function testFacade(): void\n    {\n        $pdf = Facade\\Pdf::loadHTML('<h1>Test</h1>');\n        /** @var Response $response */\n        $response = $pdf->download('test.pdf');\n\n        $this->assertInstanceOf(Response::class, $response);\n        $this->assertNotEmpty($response->getContent());\n        $this->assertEquals('application/pdf', $response->headers->get('Content-Type'));\n        $this->assertEquals('attachment; filename=test.pdf', $response->headers->get('Content-Disposition'));\n    }\n\n    public function testDownload(): void\n    {\n        $pdf = Facade\\Pdf::loadHTML('<h1>Test</h1>');\n        /** @var Response $response */\n        $response = $pdf->download('test.pdf');\n\n        $this->assertInstanceOf(Response::class, $response);\n        $this->assertNotEmpty($response->getContent());\n        $this->assertEquals('application/pdf', $response->headers->get('Content-Type'));\n        $this->assertEquals('attachment; filename=test.pdf', $response->headers->get('Content-Disposition'));\n    }\n\n    public function testStream(): void\n    {\n        $pdf = Facade\\Pdf::loadHTML('<h1>Test</h1>');\n        /** @var Response $response */\n        $response = $pdf->stream('test.pdf');\n\n        $this->assertInstanceOf(Response::class, $response);\n        $this->assertNotEmpty($response->getContent());\n        $this->assertEquals('application/pdf', $response->headers->get('Content-Type'));\n        $this->assertEquals('inline; filename=test.pdf', $response->headers->get('Content-Disposition'));\n    }\n\n    public function testView(): void\n    {\n        $pdf = Facade\\Pdf::loadView('test');\n        /** @var Response $response */\n        $response = $pdf->download('test.pdf');\n\n        $this->assertInstanceOf(Response::class, $response);\n        $this->assertNotEmpty($response->getContent());\n        $this->assertEquals('application/pdf', $response->headers->get('Content-Type'));\n        $this->assertEquals('attachment; filename=test.pdf', $response->headers->get('Content-Disposition'));\n    }\n\n    public function testQuoteFilename(): void\n    {\n        $pdf = Facade\\Pdf::loadHTML('<h1>Test</h1>');\n        /** @var Response $response */\n        $response = $pdf->download('Test file.pdf');\n\n        $this->assertInstanceOf(Response::class, $response);\n        $this->assertNotEmpty($response->getContent());\n        $this->assertEquals('application/pdf', $response->headers->get('Content-Type'));\n        $this->assertEquals('attachment; filename=\"Test file.pdf\"', $response->headers->get('Content-Disposition'));\n    }\n\n    public function testFallbackFilename(): void\n    {\n        $pdf = Facade\\Pdf::loadHTML('<h1>Test</h1>');\n        /** @var Response $response */\n        $response = $pdf->download('Test%file.pdf');\n\n        $this->assertInstanceOf(Response::class, $response);\n        $this->assertNotEmpty($response->getContent());\n        $this->assertEquals('application/pdf', $response->headers->get('Content-Type'));\n        $this->assertEquals(\"attachment; filename=Testfile.pdf; filename*=utf-8''Test%25file.pdf\", $response->headers->get('Content-Disposition'));\n    }\n\n    public function testSaveOnDisk(): void\n    {\n        $disk_name = 'local';\n        $disk = Storage::disk($disk_name);\n        $filename = 'my_stored_file_on_disk.pdf';\n\n        $pdf = Facade\\Pdf::loadView('test');\n        $pdf->save($filename, $disk_name);\n\n        $this->assertTrue($disk->exists($filename));\n\n        $content = $disk->get($filename);\n        $this->assertNotEmpty($content);\n        $this->assertEquals($content, $pdf->output());\n    }\n\n    public function testMagicMethods(): void\n    {\n        $pdf = Facade\\Pdf::setBaseHost('host')->setProtocol('protocol')\n            ->loadView('test')->setOption(['temp_dir' => 'test_dir'])\n            ->setHttpContext(['ssl' => []]);\n        /** @var Response $response */\n        $response = $pdf->download('test.pdf');\n\n        $this->assertInstanceOf(\\Barryvdh\\DomPDF\\PDF::class, $pdf);\n        $this->assertEquals('host', $pdf->getDomPDF()->getBaseHost());\n        $this->assertEquals('host', $pdf->getBaseHost());\n        $this->assertEquals('protocol', $pdf->getDomPDF()->getProtocol());\n        $this->assertEquals('protocol', $pdf->getProtocol());\n        $this->assertEquals('test_dir', $pdf->getOptions()->getTempDir());\n\n        $this->assertInstanceOf(Response::class, $response);\n        $this->assertNotEmpty($response->getContent());\n    }\n\n    public function testSave(): void\n    {\n        $filename = public_path().'/my_stored_file.pdf';\n\n        $pdf = Facade\\Pdf::loadView('test');\n        $pdf->save($filename);\n        $this->assertTrue(file_exists($filename));\n\n        $content = file_get_contents($filename);\n        $this->assertNotEmpty($content);\n        $this->assertEquals($content, $pdf->output());\n    }\n\n    public function testMultipleInstances(): void\n    {\n        $pdf1 = Facade\\Pdf::loadHTML('<h1>Test</h1>');\n        $pdf2 = Facade\\Pdf::loadHTML('<h1>Test</h1>');\n\n        $pdf1->getDomPDF()->setBaseHost('host1');\n        $pdf2->getDomPDF()->setBaseHost('host2');\n\n        $this->assertEquals('host1', $pdf1->getDomPDF()->getBaseHost());\n        $this->assertEquals('host2', $pdf2->getDomPDF()->getBaseHost());\n    }\n\n    public function testDataImage(): void\n    {\n        $pdf = Facade\\Pdf::loadHTML('<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAIAAAACUFjqAAAAEklEQVR4nGP8z4APMOGVHbHSAEEsAROxCnMTAAAAAElFTkSuQmCC\" />');\n        $response = $pdf->download('test.pdf');\n\n        $this->assertInstanceOf(Response::class, $response);\n        $this->assertNotEmpty($response->getContent());\n        $this->assertEquals(1424, strlen((string) $response->getContent()));\n    }\n}\n"
  },
  {
    "path": "tests/TestCase.php",
    "content": "<?php\n\nnamespace Barryvdh\\DomPDF\\Tests;\n\nuse Barryvdh\\DomPDF\\Facade\\Pdf;\nuse Barryvdh\\DomPDF\\ServiceProvider;\nuse Illuminate\\Support\\Facades\\View;\n\nabstract class TestCase extends \\Orchestra\\Testbench\\TestCase\n{\n    protected function setUp() : void\n    {\n        parent::setUp();\n\n        View::addLocation(__DIR__.'/views');\n    }\n\n    /**\n     * @param \\Illuminate\\Foundation\\Application $app\n     * @return string[]\n     */\n    protected function getPackageProviders($app)\n    {\n        return [ServiceProvider::class];\n    }\n\n    /**\n     * @param \\Illuminate\\Foundation\\Application $app\n     * @return string[]\n     */\n    protected function getPackageAliases($app)\n    {\n        return [\n            'PDF' => Pdf::class,\n            'Pdf' => Pdf::class,\n        ];\n    }\n}\n"
  },
  {
    "path": "tests/views/test.blade.php",
    "content": "<h1>Test</h1>"
  }
]