diff --git a/plugins/renatio/dynamicpdf/.github/ISSUE_TEMPLATE/bug_report.md b/plugins/renatio/dynamicpdf/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..dae624d --- /dev/null +++ b/plugins/renatio/dynamicpdf/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,33 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**October version** +Add October version here. + +**Plugin version** +Add plugin version here. + +**Additional context** +Add any other context about the problem here. diff --git a/plugins/renatio/dynamicpdf/.github/ISSUE_TEMPLATE/feature_request.md b/plugins/renatio/dynamicpdf/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..bbcbbe7 --- /dev/null +++ b/plugins/renatio/dynamicpdf/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/plugins/renatio/dynamicpdf/.gitignore b/plugins/renatio/dynamicpdf/.gitignore new file mode 100644 index 0000000..8b7ef35 --- /dev/null +++ b/plugins/renatio/dynamicpdf/.gitignore @@ -0,0 +1,2 @@ +/vendor +composer.lock diff --git a/plugins/renatio/dynamicpdf/LICENSE.md b/plugins/renatio/dynamicpdf/LICENSE.md new file mode 100644 index 0000000..64b24ef --- /dev/null +++ b/plugins/renatio/dynamicpdf/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) Renatio + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/plugins/renatio/dynamicpdf/Plugin.php b/plugins/renatio/dynamicpdf/Plugin.php new file mode 100644 index 0000000..87160af --- /dev/null +++ b/plugins/renatio/dynamicpdf/Plugin.php @@ -0,0 +1,108 @@ + 'renatio.dynamicpdf::lang.plugin.name', + 'description' => 'renatio.dynamicpdf::lang.plugin.description', + 'author' => 'Renatio', + 'icon' => 'octo-icon-file-pdf-o', + 'homepage' => 'https://octobercms.com/plugin/renatio-dynamicpdf', + ]; + } + + public function boot() + { + $this->app->register(ServiceProvider::class); + + $this->app->bind('dynamicpdf', function ($app) { + return new PDFWrapper($app['dompdf'], $app['config'], $app['files'], $app['view']); + }); + + (new SyncTemplates)->handle(); + } + + public function register() + { + $this->registerConsoleCommand('dynamicpdf:demo', Demo::class); + } + + public function registerPermissions() + { + return [ + 'renatio.dynamicpdf.manage_templates' => [ + 'label' => 'renatio.dynamicpdf::lang.permissions.manage_templates', + 'tab' => 'renatio.dynamicpdf::lang.permissions.tab', + ], + 'renatio.dynamicpdf.manage_layouts' => [ + 'label' => 'renatio.dynamicpdf::lang.permissions.manage_layouts', + 'tab' => 'renatio.dynamicpdf::lang.permissions.tab', + ], + ]; + } + + public function registerMarkupTags() + { + if (PluginManager::instance()->exists('RainLab.Translate')) { + return []; + } + + return [ + 'filters' => [ + '_' => ['Lang', 'get'], + '__' => ['Lang', 'choice'], + ], + ]; + } + + public function registerSettings() + { + return [ + 'templates' => [ + 'label' => 'renatio.dynamicpdf::lang.menu.label', + 'category' => 'renatio.dynamicpdf::lang.menu.category', + 'icon' => 'octo-icon-file-pdf-o', + 'url' => Backend::url('renatio/dynamicpdf/templates'), + 'description' => 'renatio.dynamicpdf::lang.menu.description', + 'permissions' => ['renatio.dynamicpdf.manage_templates'], + ], + ]; + } + + public function registerPDFTemplates() + { + if (! Parameter::get('renatio::dynamicpdf.demo')) { + return []; + } + + return [ + 'renatio.dynamicpdf::pdf.invoice', + 'renatio.dynamicpdf::pdf.header_and_footer', + ]; + } + + public function registerPDFLayouts() + { + if (! Parameter::get('renatio::dynamicpdf.demo')) { + return []; + } + + return [ + 'renatio.dynamicpdf::pdf.layouts.default', + 'renatio.dynamicpdf::pdf.layouts.header_and_footer', + ]; + } +} diff --git a/plugins/renatio/dynamicpdf/README.md b/plugins/renatio/dynamicpdf/README.md new file mode 100644 index 0000000..41bf2d4 --- /dev/null +++ b/plugins/renatio/dynamicpdf/README.md @@ -0,0 +1,571 @@ +# Dynamic PDF Plugin + +**Demo URL:** https://october-demo.renatio.com/backend/backend/auth/signin + +**Login:** dynamicpdf + +**Password:** dynamicpdf + +This plugin allows developers to create and edit PDF templates with a simple user interface. + +HTML to PDF converter uses [dompdf](https://github.com/dompdf/dompdf) library. + +Plugin uses dompdf wrapper for Laravel [barryvdh/laravel-dompdf](https://github.com/barryvdh/laravel-dompdf). + +> This plugin is fully compatible with the latest version of OctoberCMS 2.x from version 5.0.1. + +> The latest version that supports OctoberCMS 1.x is version 4.0.8. + +## Like this plugin? + +If you like this plugin, give this plugin a Like or Make donation with [PayPal](https://www.paypal.me/mplodowski). + +## My other plugins + +Please check my other [plugins](https://octobercms.com/author/Renatio). + +## Support + +Please use [GitHub Issues Page](https://github.com/mplodowski/dynamicpdf-plugin/issues) to report any issues with +plugin. + +> Reviews should not be used for getting support or reporting bugs, if you need support please use the Plugin support +> link. + +Icon made by [Darius Dan](https://www.flaticon.com/authors/darius-dan) +from [www.flaticon.com](https://www.flaticon.com/). + +# Documentation + +## Installation + +There are couple ways to install this plugin. + +1. Use `php artisan plugin:install Renatio.DynamicPDF` command. +2. Use `composer require renatio/dynamicpdf-plugin` in project root. When you use this option you must + run `php artisan october:migrate` after installation. + +## PDF content + +PDF can be created in October using either PDF views or PDF templates. A PDF view is supplied by plugin in the file +system in the **/views** directory. Whereas a PDF template is managed using the back-end interface via *Settings > PDF > +PDF Templates*. All PDFs templates support using Twig for markup. + +PDF views must be registered in the Plugin registration file with the `registerPDFTemplates` and `registerPDFLayouts` +method. This will automatically generate a PDF template and layout and allows them to be customized using the back-end +interface. + +## PDF layouts views + +PDF layouts views reside in the file system and the code used represents the path to the view file. For example PDF +layout with the code **author.plugin::pdf.layouts.default** would use the content in following file: + +``` +plugins/ <=== Plugins directory + author/ <=== "author" segment + plugin/ <=== "plugin" segment + views/ <=== View directory + pdf/ <=== "pdf" segment + layouts/ <=== "layouts" segment + default.htm <=== "default" segment +``` + +The content inside a PDF view file can include up to 3 sections: **configuration**, **CSS/LESS**, and **HTML markup**. +Sections are separated with the `==` sequence. For example: + +``` +name = "Default PDF layout" +== +body { + font-size: 16px; +} +== + + + + + Document + + + + {{ content_html|raw }} + + +``` + +> **Note:** Basic Twig tags and expressions are supported in PDF views. + +The **CSS/LESS** section is optional and a view can contain only the configuration and HTML markup sections. + +``` +name = "Default PDF layout" +== + + + + + Document + + + + {{ content_html|raw }} + + +``` + +### Configuration section + +The configuration section sets the PDF view parameters. The following configuration parameters are supported: + +| Parameter | Description | +|-----------|----------------------------| +| **name** | the layout name, required. | + +### Using PDF layouts + +PDF layouts reside in the database and can be created by selecting *Settings > PDF > PDF Templates* and clicking the * +Layouts* tab. These behave just like CMS layouts, they contain the scaffold for the PDF. PDF views and templates support +the use of PDF layouts. The **code** specified in the layout is a unique identifier and cannot be changed once created. + +## PDF templates views + +PDF templates reside in the file system and the code used represents the path to the view file. For example PDF template +with the code **author.plugin::pdf.invoice** would use the content in following file: + +``` +plugins/ <=== Plugins directory + author/ <=== "author" segment + plugin/ <=== "plugin" segment + views/ <=== View directory + pdf/ <=== "pdf" segment + invoice.htm <=== "invoice" segment +``` + +The content inside a PDF view file can include up to 2 sections: **configuration** and **HTML markup**. Sections are +separated with the `==` sequence. For example: + +``` +title = "Invoice" +layout = "renatio.demo::pdf.layouts.default" +description = "Invoice template" +size = "a4" +orientation = "portrait" +== +

Invoice

+``` + +> **Note:** Basic Twig tags and expressions are supported in PDF views. + +### Configuration section + +The configuration section sets the PDF view parameters. The following configuration parameters are supported: + +| Parameter | Description | +|-----------------|---------------------------------------------------------------| +| **title** | the template title, required. | +| **layout** | the layout code, optional. | +| **description** | the template description, optional. | +| **size** | the template paper size, optional, default `a4`. | +| **orientation** | the template paper orientation, optional, default `portrait`. | + +### Using PDF templates + +PDF templates reside in the database and can be created in the back-end area via *Settings > PDF > PDF Templates*. +The **code** specified in the template is a unique identifier and cannot be changed once created. + +> **Note:** If the PDF template does not exist in the system, this code will attempt to find a PDF view with the same +> code. + +## Registering PDF templates and layouts + +PDF views can be registered as templates that are automatically generated in the back-end ready for customization. PDF +templates can be customized via the *Settings > PDF Templates* menu. The templates can be registered by adding +the `registerPDFTemplates` method of the Plugin registration class (`Plugin.php`). + +``` +public function registerPDFTemplates() +{ + return [ + 'renatio.demo::pdf.invoice', + 'renatio.demo::pdf.resume', + ]; +} +``` + +The method should return an array of pdf view names. + +Like templates, PDF layouts can be registered by adding the `registerPDFLayouts` method of the Plugin registration +class (`Plugin.php`). + +``` +public function registerPDFLayouts() +{ + return [ + 'renatio.demo::pdf.layouts.invoice', + 'renatio.demo::pdf.layouts.resume', + ]; +} +``` + +The method should return an array of pdf view names. + +## Usage + +PDF templates and layouts can be accessed in the back-end area via *Settings > PDF > PDF Templates*. + +Layouts define the PDF scaffold, that is everything that repeats on a PDF, such as a header and footer. Each layout has +unique code, optional background image, HTML content and CSS/LESS content. Not all CSS properties are supported, so +check [CSSCompatibility](https://github.com/dompdf/dompdf/wiki/CSSCompatibility). + +Templates define the actual PDF content parsed from HTML. + +## Configuration + +The default 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: + +``` +php artisan vendor:publish --provider="Barryvdh\DomPDF\ServiceProvider" +``` + +You can still alter the dompdf options in your code before generating the PDF using dynamic methods for all options like +so: + +``` +PDF::loadTemplate('renatio::invoice') + ->setDpi(300) + ->setDefaultFont('sans-serif') + ->stream(); +``` + +Available options and their defaults: + +* __rootDir__: "{app_directory}/vendor/dompdf/dompdf" +* __tempDir__: "/tmp" _(available in config/dompdf.php)_ +* __fontDir__: "{app_directory}/storage/fonts/" _(available in config/dompdf.php)_ +* __fontCache__: "{app_directory}/storage/fonts/" _(available in config/dompdf.php)_ +* __chroot__: "{app_directory}" _(available in config/dompdf.php)_ +* __logOutputFile__: "/tmp/log.htm" +* __defaultMediaType__: "screen" _(available in config/dompdf.php)_ +* __defaultPaperSize__: "a4" _(available in config/dompdf.php)_ +* __defaultFont__: "serif" _(available in config/dompdf.php)_ +* __dpi__: 96 _(available in config/dompdf.php)_ +* __fontHeightRatio__: 1.1 _(available in config/dompdf.php)_ +* __isPhpEnabled__: false _(available in config/dompdf.php)_ +* __isRemoteEnabled__: true _(available in config/dompdf.php)_ +* __isJavascriptEnabled__: true _(available in config/dompdf.php)_ +* __isHtml5ParserEnabled__: false _(available in config/dompdf.php)_ +* __isFontSubsettingEnabled__: false _(available in config/dompdf.php)_ +* __debugPng__: false +* __debugKeepTemp__: false +* __debugCss__: false +* __debugLayout__: false +* __debugLayoutLines__: true +* __debugLayoutBlocks__: true +* __debugLayoutInline__: true +* __debugLayoutPaddingBox__: true +* __pdfBackend__: "CPDF" _(available in config/dompdf.php)_ +* __pdflibLicense__: "" +* __adminUsername__: "user" +* __adminPassword__: "password" + +See [Dompdf\Options](https://github.com/dompdf/dompdf/blob/master/src/Options.php) for a list of available options. + +## Methods + +| Method | Description | +|---------------------------------------------------------|----------------------------------------------------------| +| loadTemplate($code, array $data = [], $encoding = null) | Load backend template | +| loadLayout($code, array $data = [], $encoding = null) | Load backend layout | +| loadHTML($string, $encoding = null) | Load HTML string | +| loadFile($file) | Load HTML string from a file | +| parseTemplate(Template $template, array $data = []) | Parse backend template using Twig | +| parseLayout(Layout $layout, array $mergeData = []) | Parse backend layout using Twig | +| getDomPDF() | Get the DomPDF instance | +| setPaper($paper, $orientation = 'portrait') | Set the paper size and orientation (default A4/portrait) | +| setWarnings($warnings) | Show or hide warnings | +| output() | Output the PDF as a string | +| save($filename) | Save the PDF to a file | +| download($filename = 'document.pdf') | Make the PDF downloadable by the user | +| stream($filename = 'document.pdf') | Return a response with the PDF to show in the browser | + +All methods are available through Facade class `Renatio\DynamicPDF\Classes\PDF`. + +## Tips + +### Background image + +To display background image added in layout use following code: + +``` + +``` + +Background image should be at least 96 DPI size (793 x 1121 px). + +If you want to use better quality image like 300 DPI (2480 x 3508 px) than you need to change template options like so: + +``` +return PDF::loadTemplate($model->code) + ->setDpi(300) + ->stream(); +``` + +### UTF-8 support + +In your layout, set the UTF-8 meta tag in `head` section: + +``` + +``` + +If you have problems with foreign characters than try to use **DejaVu Sans** font family. + +### Page breaks + +You can use the CSS page-break-before/page-break-after properties to create a new page. + +``` + +

Page 1

+
+

Page 2

+``` + +### Open basedir restriction error + +On some hosting providers there were reports about `open_basedir` restriction problems with log file. You can change +default log file destination like so: + +``` +return PDF::loadTemplate('renatio::invoice') + ->setLogOutputFile(storage_path('temp/log.htm')) + ->stream(); +``` + +### Embed image inside PDF template + +You can use absolute path for image eg. `https://app.dev/path_to_your_image`. + +For this to work you must set `isRemoteEnabled` option. + +``` +return PDF::loadTemplate('renatio::invoice', ['file' => $file]) + ->setIsRemoteEnabled(true) + ->stream(); +``` + +I assume that `$file` is instance of `October\Rain\Database\Attach\File`. + +Then in the template you can use following example code: + +``` +{{ file.getPath }} + +{{ file.getLocalPath }} + +{{ file.getThumb(200, 200, {'crop' => true}) }} +``` + +> For retrieving stylesheets or images via http following PHP setting must be enabled `allow_url_fopen`. + +When `allow_url_fopen` is disabled on server try to use relative path. You can use October `getLocalPath` function on +the file object to retrieve it. + +### Download PDF via Ajax response + +OctoberCMS ajax framework cannot handle this type of response. + +Recommended approach is to save PDF file locally and return redirect to PDF file. + +### Page numbers + +Page numbers can be generated using PHP. Inline PHP is disabled by default, because it can be a security risk. You can +enable inline PHP using `setIsPhpEnabled` method. + +``` +return PDF::loadTemplate('renatio::invoice') + ->setIsRemoteEnabled(true) + ->setIsPhpEnabled(true) + ->stream(); +``` + +After that you must place following code after `` tag of the layout file. + +``` + +``` + +## Examples + +### Demo examples + +There is a console command that will enable demo templates and layouts. + +``` +php artisan dynamicpdf:demo +``` + +To disable demo run following command: + +``` +php artisan dynamicpdf:demo --disable +``` + +The first example shows invoice with custom font and image embed. + +The second example shows usage of header & footer, page break, page numbers and full background image. + +### Render PDF in browser + +``` +use Renatio\DynamicPDF\Classes\PDF; // import facade + +public function pdf() +{ + $templateCode = 'renatio::invoice'; // unique code of the template + $data = ['name' => 'John Doe']; // optional data used in template + + return PDF::loadTemplate($templateCode, $data)->stream('download.pdf'); +} +``` + +Where `$templateCode` is an unique code specified when creating the template, `$data` is optional array of twig fields +which will be replaced in template. + +In HTML template you can use `{{ name }}` to output `John Doe`. + +### Download PDF + +``` +use Renatio\DynamicPDF\Classes\PDF; + +public function pdf() +{ + return PDF::loadTemplate('renatio::invoice')->download('download.pdf'); +} +``` + +### Fluent interface + +You can chain the methods: + +``` +return PDF::loadTemplate('renatio::invoice') + ->save('/path-to/my_stored_file.pdf') + ->stream(); +``` + +### Change paper size and orientation + +``` +return PDF::loadTemplate('renatio::invoice') + ->setPaper('a4', 'landscape') + ->stream(); +``` + +Available [paper sizes](https://github.com/dompdf/dompdf/blob/master/src/Adapter/CPDF.php#L40). + +### PDF on CMS page + +To display PDF on CMS page you can use PHP section of the page like so: + +``` +use Renatio\DynamicPDF\Classes\PDF; + +function onStart() +{ + return PDF::loadTemplate('renatio::invoice')->stream(); +} +``` + +### Header and footer on every page + +``` + + + + + +
header on each page
+ +
+

page1

+

page2

+
+ + +``` + +### Using custom fonts + +Plugin provides "Open Sans" font, which can be imported in Layout CSS section. + +``` +@font-face { + font-family: 'Open Sans'; + src: url({{ 'plugins/renatio/dynamicpdf/assets/fonts/OpenSans-Regular.ttf'|app }}); +} + +@font-face { + font-family: 'Open Sans'; + font-weight: bold; + src: url({{ 'plugins/renatio/dynamicpdf/assets/fonts/OpenSans-Bold.ttf'|app }}); +} + +@font-face { + font-family: 'Open Sans'; + font-style: italic; + src: url({{ 'plugins/renatio/dynamicpdf/assets/fonts/OpenSans-Italic.ttf'|app }}); +} + +@font-face { + font-family: 'Open Sans'; + font-style: italic; + font-weight: bold; + src: url({{ 'plugins/renatio/dynamicpdf/assets/fonts/OpenSans-BoldItalic.ttf'|app }}); +} + +body { + font-family: 'Open Sans', sans-serif; + font-size: 16px; +} +``` diff --git a/plugins/renatio/dynamicpdf/UPGRADE.md b/plugins/renatio/dynamicpdf/UPGRADE.md new file mode 100644 index 0000000..be22acc --- /dev/null +++ b/plugins/renatio/dynamicpdf/UPGRADE.md @@ -0,0 +1,59 @@ +# Upgrade guide + +## Upgrading To 1.1.0 + +Plugin requires October build 300+. + +## Upgrading To 2.0.0 + +`PDFTemplate::render()` method was removed. Please switch to `Renatio\DynamicPDF\Classes\PDF` facade. + +## Upgrading To 2.1.0 + +Method `setOrientation` was removed. Use `setPaper` instead. + +## Upgrading To 2.1.1 + +Plugin requires **Stable** version of October and PHP >=5.5.9. + +## Upgrading To 3.0.0 + +Plugin requires OctoberCMS build 420+ with Laravel 5.5 and PHP >=7.0. + +## Upgrading To 4.0.0 + +Plugin requires PHP >=7.1 to work with the latest version of [dompdf](https://github.com/dompdf/dompdf) library. + +For October composer based installation you must manually update project composer.json file to use at least PHP 7.1: + +``` +"config": { + "preferred-install": "dist", + "platform": { + "php": "7.1" + } +}, +``` + +After this change run `composer update` command. + +## Upgrading To 4.0.8 + +This is the latest version with support for October 1.x. + +Using `setOptions` method to change dompdf options is no longer recommended. This will cause to override all laravel +dompdf configuration and use only specified by method argument and dompdf defaults for rest options not set by a +developer. + +Instead of using this method, please use dynamic method call for option you would like to change. Please read more +in [documentation](https://github.com/mplodowski/dynamicpdf-plugin/blob/master/README.md#configuration-configuration). + +## Upgrading To 5.0.1 + +Plugin requires OctoberCMS v2.1.x with Laravel 6 and PHP >=7.2. + +## Upgrading To 6.0.0 + +Plugin requires October CMS version 3.0 or higher, Laravel 9.0 or higher and PHP >=8.0. + +Drop support for October CMS version 2.x. diff --git a/plugins/renatio/dynamicpdf/assets/css/tailwind.css b/plugins/renatio/dynamicpdf/assets/css/tailwind.css new file mode 100644 index 0000000..16256da --- /dev/null +++ b/plugins/renatio/dynamicpdf/assets/css/tailwind.css @@ -0,0 +1,766 @@ +/*! tailwindcss v2.2.19 | MIT License | https://tailwindcss.com */ + +/*! modern-normalize v1.1.0 | MIT License | https://github.com/sindresorhus/modern-normalize */ + +/* +Document +======== +*/ + +/** +Use a better box model (opinionated). +*/ + +*, +::before, +::after { + box-sizing: border-box; +} + +/** +Use a more readable tab size (opinionated). +*/ + +html { + -moz-tab-size: 4; + tab-size: 4; +} + +/** +1. Correct the line height in all browsers. +2. Prevent adjustments of font size after orientation changes in iOS. +*/ + +html { + line-height: 1.15; + /* 1 */ + -webkit-text-size-adjust: 100%; + /* 2 */ +} + +/* +Sections +======== +*/ + +/** +Remove the margin in all browsers. +*/ + +body { + margin: 0; +} + +/** +Improve consistency of default fonts in all browsers. (https://github.com/sindresorhus/modern-normalize/issues/3) +*/ + +body { + font-family: + system-ui, + -apple-system, /* Firefox supports this but not yet `system-ui` */ + 'Segoe UI', + Roboto, + Helvetica, + Arial, + sans-serif, + 'Apple Color Emoji', + 'Segoe UI Emoji'; +} + +/* +Grouping content +================ +*/ + +/** +1. Add the correct height in Firefox. +2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655) +*/ + +hr { + height: 0; + /* 1 */ + color: inherit; + /* 2 */ +} + +/* +Text-level semantics +==================== +*/ + +/** +Add the correct text decoration in Chrome, Edge, and Safari. +*/ + +abbr[title] { + text-decoration: underline dotted; +} + +/** +Add the correct font weight in Edge and Safari. +*/ + +b, +strong { + font-weight: bolder; +} + +/** +1. Improve consistency of default fonts in all browsers. (https://github.com/sindresorhus/modern-normalize/issues/3) +2. Correct the odd 'em' font sizing in all browsers. +*/ + +code, +kbd, +samp, +pre { + font-family: + ui-monospace, + SFMono-Regular, + Consolas, + 'Liberation Mono', + Menlo, + monospace; + /* 1 */ + font-size: 1em; + /* 2 */ +} + +/** +Add the correct font size in all browsers. +*/ + +small { + font-size: 80%; +} + +/** +Prevent 'sub' and 'sup' elements from affecting the line height in all browsers. +*/ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +/* +Tabular data +============ +*/ + +/** +1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) +2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) +*/ + +table { + text-indent: 0; + /* 1 */ + border-color: inherit; + /* 2 */ +} + +/* +Forms +===== +*/ + +/** +1. Change the font styles in all browsers. +2. Remove the margin in Firefox and Safari. +*/ + +button, +input, +optgroup, +select, +textarea { + font-family: inherit; + /* 1 */ + font-size: 100%; + /* 1 */ + line-height: 1.15; + /* 1 */ + margin: 0; + /* 2 */ +} + +/** +Remove the inheritance of text transform in Edge and Firefox. +1. Remove the inheritance of text transform in Firefox. +*/ + +button, +select { + /* 1 */ + text-transform: none; +} + +/** +Correct the inability to style clickable types in iOS and Safari. +*/ + +button, +[type='button'] { + -webkit-appearance: button; +} + +/** +Remove the inner border and padding in Firefox. +*/ + +/** +Restore the focus styles unset by the previous rule. +*/ + +/** +Remove the additional ':invalid' styles in Firefox. +See: https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737 +*/ + +/** +Remove the padding so developers are not caught out when they zero out 'fieldset' elements in all browsers. +*/ + +legend { + padding: 0; +} + +/** +Add the correct vertical alignment in Chrome and Firefox. +*/ + +progress { + vertical-align: baseline; +} + +/** +Correct the cursor style of increment and decrement buttons in Safari. +*/ + +/** +1. Correct the odd appearance in Chrome and Safari. +2. Correct the outline style in Safari. +*/ + +/** +Remove the inner padding in Chrome and Safari on macOS. +*/ + +/** +1. Correct the inability to style clickable types in iOS and Safari. +2. Change font properties to 'inherit' in Safari. +*/ + +/* +Interactive +=========== +*/ + +/* +Add the correct display in Chrome and Safari. +*/ + +summary { + display: list-item; +} + +/** + * Manually forked from SUIT CSS Base: https://github.com/suitcss/base + * A thin layer on top of normalize.css that provides a starting point more + * suitable for web applications. + */ + +/** + * Removes the default spacing and border for appropriate elements. + */ + +blockquote, +dl, +dd, +h1, +h2, +h3, +h4, +h5, +h6, +hr, +figure, +p, +pre { + margin: 0; +} + +button { + background-color: transparent; + background-image: none; +} + +fieldset { + margin: 0; + padding: 0; +} + +ol, +ul { + list-style: none; + margin: 0; + padding: 0; +} + +/** + * Tailwind custom reset styles + */ + +/** + * 1. Use the user's configured `sans` font-family (with Tailwind's default + * sans-serif font stack as a fallback) as a sane default. + * 2. Use Tailwind's default "normal" line-height so the user isn't forced + * to override it to ensure consistency even when using the default theme. + */ + +html { + font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + /* 1 */ + line-height: 1.5; + /* 2 */ +} + +/** + * Inherit font-family and line-height from `html` so users can set them as + * a class directly on the `html` element. + */ + +body { + font-family: inherit; + line-height: inherit; +} + +/** + * 1. Prevent padding and border from affecting element width. + * + * We used to set this in the html element and inherit from + * the parent element for everything else. This caused issues + * in shadow-dom-enhanced elements like
where the content + * is wrapped by a div with box-sizing set to `content-box`. + * + * https://github.com/mozdevs/cssremedy/issues/4 + * + * + * 2. Allow adding a border to an element by just adding a border-width. + * + * By default, the way the browser specifies that an element should have no + * border is by setting it's border-style to `none` in the user-agent + * stylesheet. + * + * In order to easily add borders to elements by just setting the `border-width` + * property, we change the default border-style for all elements to `solid`, and + * use border-width to hide them instead. This way our `border` utilities only + * need to set the `border-width` property instead of the entire `border` + * shorthand, making our border utilities much more straightforward to compose. + * + * https://github.com/tailwindcss/tailwindcss/pull/116 + */ + +*, +::before, +::after { + box-sizing: border-box; + /* 1 */ + border-width: 0; + /* 2 */ + border-style: solid; + /* 2 */ + border-color: currentColor; + /* 2 */ +} + +/* + * Ensure horizontal rules are visible by default + */ + +hr { + border-top-width: 1px; +} + +/** + * Undo the `border-style: none` reset that Normalize applies to images so that + * our `border-{width}` utilities have the expected effect. + * + * The Normalize reset is unnecessary for us since we default the border-width + * to 0 on all elements. + * + * https://github.com/tailwindcss/tailwindcss/issues/362 + */ + +img { + border-style: solid; +} + +textarea { + resize: vertical; +} + +input::placeholder, +textarea::placeholder { + opacity: 1; + color: #9ca3af; +} + +button { + cursor: pointer; +} + +/** + * Override legacy focus reset from Normalize with modern Firefox focus styles. + * + * This is actually an improvement over the new defaults in Firefox in our testing, + * as it triggers the better focus styles even for links, which still use a dotted + * outline in Firefox by default. + */ + +table { + border-collapse: collapse; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + font-size: inherit; + font-weight: inherit; +} + +/** + * Reset links to optimize for opt-in styling instead of + * opt-out. + */ + +a { + color: inherit; + text-decoration: inherit; +} + +/** + * Reset form element properties that are easy to forget to + * style explicitly so you don't inadvertently introduce + * styles that deviate from your design system. These styles + * supplement a partial reset that is already applied by + * normalize.css. + */ + +button, +input, +optgroup, +select, +textarea { + padding: 0; + line-height: inherit; + color: inherit; +} + +/** + * Use the configured 'mono' font family for elements that + * are expected to be rendered with a monospace font, falling + * back to the system monospace stack if there is no configured + * 'mono' font family. + */ + +pre, +code, +kbd, +samp { + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; +} + +/** + * 1. Make replaced elements `display: block` by default as that's + * the behavior you want almost all of the time. Inspired by + * CSS Remedy, with `svg` added as well. + * + * https://github.com/mozdevs/cssremedy/issues/14 + * + * 2. Add `vertical-align: middle` to align replaced elements more + * sensibly by default when overriding `display` by adding a + * utility like `inline`. + * + * This can trigger a poorly considered linting error in some + * tools but is included by design. + * + * https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210 + */ + +img, +svg, +video, +canvas, +audio, +iframe, +embed, +object { + display: block; + /* 1 */ + vertical-align: middle; + /* 2 */ +} + +/** + * Constrain images and videos to the parent width and preserve + * their intrinsic aspect ratio. + * + * https://github.com/mozdevs/cssremedy/issues/14 + */ + +img, +video { + max-width: 100%; + height: auto; +} + +/** + * Ensure the default browser behavior of the `hidden` attribute. + */ + +*, ::before, ::after { + border-color: #e5e7eb; +} + +.fixed { + position: fixed; +} + +.top-0 { + top: 0px; +} + +.bottom-0 { + bottom: 0px; +} + +.float-right { + float: right; +} + +.float-left { + float: left; +} + +.clear-both { + clear: both; +} + +.my-8 { + margin-top: 2rem; + margin-bottom: 2rem; +} + +.mt-4 { + margin-top: 1rem; +} + +.mt-8 { + margin-top: 2rem; +} + +.mt-20 { + margin-top: 5rem; +} + +.mb-2 { + margin-bottom: 0.5rem; +} + +.mb-4 { + margin-bottom: 1rem; +} + +.table { + display: table; +} + +.h-24 { + height: 6rem; +} + +.h-32 { + height: 8rem; +} + +.w-16 { + width: 4rem; +} + +.w-1\/2 { + width: 50%; +} + +.w-full { + width: 100%; +} + +.border-2 { + border-width: 2px; +} + +.border-b { + border-bottom-width: 1px; +} + +.border-solid { + border-style: solid; +} + +.border-gray-700 { + border-color: #374151; +} + +.border-gray-800 { + border-color: #1f2937; +} + +.bg-left-top { + background-position: left top; +} + +.bg-no-repeat { + background-repeat: no-repeat; +} + +.p-16 { + padding: 4rem; +} + +.px-12 { + padding-left: 3rem; + padding-right: 3rem; +} + +.py-2 { + padding-top: 0.5rem; + padding-bottom: 0.5rem; +} + +.py-4 { + padding-top: 1rem; + padding-bottom: 1rem; +} + +.pt-36 { + padding-top: 9rem; +} + +.pb-1 { + padding-bottom: 0.25rem; +} + +.pb-4 { + padding-bottom: 1rem; +} + +.pb-20 { + padding-bottom: 5rem; +} + +.text-left { + text-align: left; +} + +.text-center { + text-align: center; +} + +.text-right { + text-align: right; +} + +.text-sm { + font-size: 0.875rem; + line-height: 1.25rem; +} + +.text-lg { + font-size: 1.125rem; + line-height: 1.75rem; +} + +.text-xl { + font-size: 1.25rem; + line-height: 1.75rem; +} + +.text-2xl { + font-size: 1.5rem; + line-height: 2rem; +} + +.text-3xl { + font-size: 1.875rem; + line-height: 2.25rem; +} + +.text-4xl { + font-size: 2.25rem; + line-height: 2.5rem; +} + +.font-normal { + font-weight: 400; +} + +.font-bold { + font-weight: 700; +} + +.uppercase { + text-transform: uppercase; +} + +.leading-none { + line-height: 1; +} + +.text-gray-400 { + color: #9ca3af; +} + +.text-gray-500 { + color: #6b7280; +} + +.text-gray-700 { + color: #374151; +} + +.text-gray-800 { + color: #1f2937; +} + +@media (min-width: 640px) { +} + +@media (min-width: 768px) { +} + +@media (min-width: 1024px) { +} + +@media (min-width: 1280px) { +} + +@media (min-width: 1536px) { +} \ No newline at end of file diff --git a/plugins/renatio/dynamicpdf/assets/fonts/OpenSans-Bold.ttf b/plugins/renatio/dynamicpdf/assets/fonts/OpenSans-Bold.ttf new file mode 100644 index 0000000..fd79d43 Binary files /dev/null and b/plugins/renatio/dynamicpdf/assets/fonts/OpenSans-Bold.ttf differ diff --git a/plugins/renatio/dynamicpdf/assets/fonts/OpenSans-BoldItalic.ttf b/plugins/renatio/dynamicpdf/assets/fonts/OpenSans-BoldItalic.ttf new file mode 100644 index 0000000..9bc8009 Binary files /dev/null and b/plugins/renatio/dynamicpdf/assets/fonts/OpenSans-BoldItalic.ttf differ diff --git a/plugins/renatio/dynamicpdf/assets/fonts/OpenSans-Italic.ttf b/plugins/renatio/dynamicpdf/assets/fonts/OpenSans-Italic.ttf new file mode 100644 index 0000000..c90da48 Binary files /dev/null and b/plugins/renatio/dynamicpdf/assets/fonts/OpenSans-Italic.ttf differ diff --git a/plugins/renatio/dynamicpdf/assets/fonts/OpenSans-Regular.ttf b/plugins/renatio/dynamicpdf/assets/fonts/OpenSans-Regular.ttf new file mode 100644 index 0000000..db43334 Binary files /dev/null and b/plugins/renatio/dynamicpdf/assets/fonts/OpenSans-Regular.ttf differ diff --git a/plugins/renatio/dynamicpdf/assets/img/bg.jpg b/plugins/renatio/dynamicpdf/assets/img/bg.jpg new file mode 100644 index 0000000..c4afc81 Binary files /dev/null and b/plugins/renatio/dynamicpdf/assets/img/bg.jpg differ diff --git a/plugins/renatio/dynamicpdf/assets/img/october.png b/plugins/renatio/dynamicpdf/assets/img/october.png new file mode 100644 index 0000000..1fc6830 Binary files /dev/null and b/plugins/renatio/dynamicpdf/assets/img/october.png differ diff --git a/plugins/renatio/dynamicpdf/assets/js/tailwind.config.js b/plugins/renatio/dynamicpdf/assets/js/tailwind.config.js new file mode 100644 index 0000000..0a853a6 --- /dev/null +++ b/plugins/renatio/dynamicpdf/assets/js/tailwind.config.js @@ -0,0 +1,161 @@ +module.exports = { + purge: [ + './plugins/renatio/dynamicpdf/views/pdf/*.htm', + './plugins/renatio/dynamicpdf/views/pdf/layouts/*.htm', + ], + darkMode: false, + theme: { + extend: { + screens: {}, + }, + }, + variants: { + extend: {}, + }, + plugins: [], + corePlugins: { + accessibility: false, + alignContent: false, + alignItems: false, + alignSelf: false, + animation: false, + appearance: false, + backdropBlur: false, + backdropBrightness: false, + backdropContrast: false, + backdropFilter: false, + backdropGrayscale: false, + backdropHueRotate: false, + backdropInvert: false, + backdropOpacity: false, + backdropSaturate: false, + backdropSepia: false, + backgroundAttachment: [], + backgroundBlendMode: false, + backgroundClip: false, + backgroundColor: [], + backgroundImage: [], + backgroundOpacity: false, + backgroundPosition: [], + backgroundRepeat: [], + backgroundSize: [], + backgroundOrigin: [], + blur: false, + borderCollapse: [], + borderColor: [], + borderOpacity: false, + borderRadius: [], + borderStyle: [], + borderWidth: [], + boxDecorationBreak: false, + boxShadow: false, + boxSizing: false, + brightness: false, + clear: [], + container: false, + contrast: false, + cursor: false, + display: [], + divideColor: false, + divideOpacity: false, + divideStyle: false, + divideWidth: false, + dropShadow: false, + fill: false, + filter: false, + flex: false, + flexDirection: false, + flexGrow: false, + flexShrink: false, + flexWrap: false, + float: [], + fontFamily: [], + fontSize: [], + fontSmoothing: false, + fontStyle: [], + fontVariantNumeric: false, + fontWeight: [], + gap: false, + gradientColorStops: false, + grayscale: false, + gridAutoColumns: false, + gridAutoFlow: false, + gridAutoRows: false, + gridColumn: false, + gridColumnEnd: false, + gridColumnStart: false, + gridRow: false, + gridRowEnd: false, + gridRowStart: false, + gridTemplateColumns: false, + gridTemplateRows: false, + height: [], + hueRotate: false, + inset: [], + invert: false, + isolation: false, + justifyContent: false, + justifyItems: false, + justifySelf: false, + letterSpacing: [], + lineHeight: [], + listStylePosition: [], + listStyleType: [], + margin: [], + maxHeight: [], + maxWidth: [], + minHeight: [], + minWidth: [], + mixBlendMode: false, + objectFit: false, + objectPosition: false, + opacity: false, + order: false, + outline: [], + overflow: [], + overscrollBehavior: false, + padding: [], + placeContent: false, + placeItems: false, + placeSelf: false, + placeholderColor: false, + placeholderOpacity: false, + pointerEvents: false, + position: [], + resize: false, + ringColor: false, + ringOffsetColor: false, + ringOffsetWidth: false, + ringOpacity: false, + ringWidth: false, + rotate: false, + saturate: false, + scale: false, + sepia: false, + skew: false, + space: false, + stroke: false, + strokeWidth: false, + tableLayout: [], + textAlign: [], + textColor: [], + textDecoration: [], + textOpacity: false, + textOverflow: [], + textTransform: [], + transform: false, + transformOrigin: false, + transitionDelay: false, + transitionDuration: false, + transitionProperty: false, + transitionTimingFunction: false, + translate: false, + userSelect: false, + verticalAlign: [], + visibility: [], + whitespace: [], + width: [], + wordBreak: [], + zIndex: [], + } +} diff --git a/plugins/renatio/dynamicpdf/classes/PDF.php b/plugins/renatio/dynamicpdf/classes/PDF.php new file mode 100644 index 0000000..b3b10fd --- /dev/null +++ b/plugins/renatio/dynamicpdf/classes/PDF.php @@ -0,0 +1,13 @@ +getPlugins(); + + foreach ($plugins as $plugin) { + if (method_exists($plugin, 'registerPDFLayouts')) { + $layouts = $plugin->registerPDFLayouts(); + + if (is_array($layouts)) { + $this->registerLayouts($layouts); + } + } + + if (method_exists($plugin, 'registerPDFTemplates')) { + $templates = $plugin->registerPDFTemplates(); + + if (is_array($templates)) { + $this->registerTemplates($templates); + } + } + } + } + + public function listRegisteredLayouts() + { + if ($this->registeredLayouts === null) { + $this->loadRegisteredTemplates(); + } + + return $this->registeredLayouts; + } + + public function listRegisteredTemplates() + { + if ($this->registeredTemplates === null) { + $this->loadRegisteredTemplates(); + } + + return $this->registeredTemplates; + } + + public function registerLayouts(array $definitions) + { + if (! $this->registeredLayouts) { + $this->registeredLayouts = []; + } + + $definitions = array_combine($definitions, $definitions); + + $this->registeredLayouts = $definitions + $this->registeredLayouts; + } + + public function registerTemplates(array $definitions) + { + if (! $this->registeredTemplates) { + $this->registeredTemplates = []; + } + + $definitions = array_combine($definitions, $definitions); + + $this->registeredTemplates = $definitions + $this->registeredTemplates; + } +} diff --git a/plugins/renatio/dynamicpdf/classes/PDFParser.php b/plugins/renatio/dynamicpdf/classes/PDFParser.php new file mode 100644 index 0000000..05a57c3 --- /dev/null +++ b/plugins/renatio/dynamicpdf/classes/PDFParser.php @@ -0,0 +1,45 @@ + [], + 'css' => null, + 'html' => null, + ]; + + if ($count >= 3) { + $result['settings'] = parse_ini_string($sections[0], true); + $result['css'] = $sections[1]; + $result['html'] = $sections[2]; + } elseif ($count == 2) { + $result['settings'] = parse_ini_string($sections[0], true); + $result['html'] = $sections[1]; + } elseif ($count == 1) { + $result['html'] = $sections[0]; + } + + return $result; + } + + public static function sections($path) + { + return PDFParser::parse(File::get(View::make($path)->getPath())); + } +} diff --git a/plugins/renatio/dynamicpdf/classes/PDFWrapper.php b/plugins/renatio/dynamicpdf/classes/PDFWrapper.php new file mode 100644 index 0000000..f464efd --- /dev/null +++ b/plugins/renatio/dynamicpdf/classes/PDFWrapper.php @@ -0,0 +1,108 @@ +getDomPDF()->getOptions(); + + if (method_exists($options, $method)) { + call_user_func_array([$options, $method], $args); + } + + return $this; + } + + public function loadTemplate($code, $data = [], $encoding = null) + { + $template = Template::byCode($code); + + $this->loadHTML( + $this->parseTemplate($template, $data), + $encoding + ); + + if ($template->size) { + $this->setPaper($template->size, $template->orientation ?? 'portrait'); + } + + return $this; + } + + public function loadLayout($code, $data = [], $encoding = null) + { + $this->loadHTML( + $this->parseLayout(Layout::byCode($code), $data), + $encoding + ); + + return $this; + } + + public function parseTemplate($template, $data = []) + { + $this->setLocale(); + + $html = $this->parseMarkup($template->content_html, $data); + + if (! $template->layout) { + return $html; + } + + return $this->parseLayout( + $template->layout, + array_merge(['content_html' => $html], $data) + ); + } + + public function parseLayout($layout, $data = []) + { + $this->setLocale(); + + return $this->parseMarkup( + $layout->content_html, + $this->layoutData($layout, $data) + ); + } + + protected function setLocale() + { + if (! PluginManager::instance()->exists('RainLab.Translate')) { + return; + } + + Message::$locale = Translator::instance()->getLocale(); + } + + protected function layoutData($layout, $data) + { + return array_merge([ + 'background_img' => $layout->background_img ? $layout->background_img->getPath() : null, + 'css' => $layout->getCSS(), + ], $data); + } + + protected function parseMarkup($markup, $data) + { + try { + $twig = (new Controller)->getTwig(); + $template = $twig->createTemplate($markup); + + return $template->render($data); + } catch (Exception $e) { + return Twig::parse($markup, $data); + } + } +} diff --git a/plugins/renatio/dynamicpdf/classes/SyncTemplates.php b/plugins/renatio/dynamicpdf/classes/SyncTemplates.php new file mode 100644 index 0000000..42385bb --- /dev/null +++ b/plugins/renatio/dynamicpdf/classes/SyncTemplates.php @@ -0,0 +1,96 @@ +checkFontsDir(); + + $this->checkPublicDir(); + + $this->createLayouts(); + + $registeredTemplates = PDFManager::instance()->listRegisteredTemplates(); + + if (! $registeredTemplates) { + return; + } + + $dbTemplates = Template::lists('is_custom', 'code'); + + $this->clearNonCustomizedTemplates($dbTemplates, $registeredTemplates); + + $newTemplates = array_diff_key($registeredTemplates, $dbTemplates); + + $this->createTemplates($newTemplates); + } catch (Exception $e) { + // + } + } + + protected function createLayouts() + { + $registeredLayouts = PDFManager::instance()->listRegisteredLayouts(); + + if (! $registeredLayouts) { + return; + } + + $dbLayouts = Layout::lists('code', 'code'); + + foreach ($registeredLayouts as $code) { + if (array_key_exists($code, $dbLayouts)) { + continue; + } + + $layout = new Layout; + $layout->code = $code; + $layout->is_locked = true; + $layout->fillFromView($code); + $layout->save(); + } + } + + protected function clearNonCustomizedTemplates($dbTemplates, $registeredTemplates) + { + foreach ($dbTemplates as $code => $isCustom) { + if ($isCustom) { + continue; + } + + if (! array_key_exists($code, $registeredTemplates)) { + Template::whereCode($code)->delete(); + } + } + } + + protected function createTemplates($templates) + { + foreach ($templates as $code) { + $template = new Template; + $template->fillFromView($code); + $template->forceSave(); + } + } + + protected function checkFontsDir() + { + if (! file_exists(config('dompdf.defines.font_dir'))) { + mkdir(config('dompdf.defines.font_dir'), 0755, true); + } + } + + protected function checkPublicDir() + { + if (! file_exists('public')) { + mkdir('public', 0755, true); + } + } +} diff --git a/plugins/renatio/dynamicpdf/composer.json b/plugins/renatio/dynamicpdf/composer.json new file mode 100644 index 0000000..cef6876 --- /dev/null +++ b/plugins/renatio/dynamicpdf/composer.json @@ -0,0 +1,25 @@ +{ + "name": "renatio/dynamicpdf-plugin", + "type": "october-plugin", + "description": "October HTML to PDF converter using dompdf library.", + "homepage": "https://octobercms.com/plugin/renatio-dynamicpdf", + "keywords": [ + "octobercms-plugin", + "octobercms", + "php", + "laravel", + "pdf", + "dompdf" + ], + "license": "MIT", + "authors": [ + { + "name": "Michal Plodowski", + "email": "michal.plodowski@gmail.com" + } + ], + "require": { + "barryvdh/laravel-dompdf": "^1.0", + "composer/installers": "~1.0" + } +} diff --git a/plugins/renatio/dynamicpdf/console/Demo.php b/plugins/renatio/dynamicpdf/console/Demo.php new file mode 100644 index 0000000..770894f --- /dev/null +++ b/plugins/renatio/dynamicpdf/console/Demo.php @@ -0,0 +1,49 @@ +option('disable')) { + $this->disableDemo(); + } else { + $this->enableDemo(); + } + } + + protected function enableDemo() + { + Parameter::set('renatio::dynamicpdf.demo', 1); + + $this->info(e(trans('renatio.dynamicpdf::lang.demo.enabled'))); + } + + protected function disableDemo() + { + $plugin = PluginManager::instance()->findByNamespace('Renatio.DynamicPDF'); + + foreach ($plugin->registerPDFTemplates() as $template) { + Template::where('code', $template)->delete(); + } + + foreach ($plugin->registerPDFLayouts() as $layout) { + Layout::where('code', $layout)->delete(); + } + + Parameter::set('renatio::dynamicpdf.demo', 0); + + $this->info(e(trans('renatio.dynamicpdf::lang.demo.disabled'))); + } +} diff --git a/plugins/renatio/dynamicpdf/controllers/Layouts.php b/plugins/renatio/dynamicpdf/controllers/Layouts.php new file mode 100644 index 0000000..0b952f5 --- /dev/null +++ b/plugins/renatio/dynamicpdf/controllers/Layouts.php @@ -0,0 +1,67 @@ +pageTitle = e(trans('renatio.dynamicpdf::lang.templates.preview_pdf')); + + try { + $model = $this->formFindModelObject($id); + } catch (ApplicationException $e) { + return $this->handleError($e); + } + + return PDF::loadLayout($model->code) + ->setLogOutputFile(storage_path('temp/log.htm')) + ->setIsRemoteEnabled(true) + ->setDpi(300) + ->setIsPhpEnabled(true) + ->stream(); + } + + public function html($id) + { + $model = $this->formFindModelObject($id); + + return response($model->html); + } + + public function update_onResetDefault($recordId) + { + $model = $this->formFindModelObject($recordId); + + $model->fillFromCode(); + $model->save(); + + Flash::success(e(trans('backend::lang.form.reset_success'))); + + return redirect()->refresh(); + } +} diff --git a/plugins/renatio/dynamicpdf/controllers/Templates.php b/plugins/renatio/dynamicpdf/controllers/Templates.php new file mode 100644 index 0000000..ad6a8b7 --- /dev/null +++ b/plugins/renatio/dynamicpdf/controllers/Templates.php @@ -0,0 +1,88 @@ + 'config_templates_list.yaml', + 'layouts' => 'config_layouts_list.yaml', + ]; + + public $formConfig = 'config_form.yaml'; + + public function __construct() + { + parent::__construct(); + + BackendMenu::setContext('October.System', 'system', 'settings'); + SettingsManager::setContext('Renatio.DynamicPDF', 'templates'); + } + + public function index($tab = null) + { + $this->asExtension('ListController')->index(); + + $this->bodyClass = 'compact-container'; + $this->vars['activeTab'] = $tab ?: 'templates'; + } + + public function formBeforeSave($model) + { + $model->is_custom = 1; + } + + public function previewPdf($id) + { + $this->pageTitle = e(trans('renatio.dynamicpdf::lang.templates.preview_pdf')); + + try { + $model = $this->formFindModelObject($id); + } catch (ApplicationException $e) { + return $this->handleError($e); + } + + return PDF::loadTemplate($model->code) + ->setLogOutputFile(storage_path('temp/log.htm')) + ->setIsRemoteEnabled(true) + ->setDpi(300) + ->setIsPhpEnabled(true) + ->stream(); + } + + public function html($id) + { + $model = $this->formFindModelObject($id); + + return response($model->html); + } + + public function update_onResetDefault($recordId) + { + $model = $this->formFindModelObject($recordId); + + $model->fillFromCode(); + $model->is_custom = 0; + $model->save(); + + Flash::success(e(trans('backend::lang.form.reset_success'))); + + return redirect()->refresh(); + } +} diff --git a/plugins/renatio/dynamicpdf/controllers/layouts/config_form.yaml b/plugins/renatio/dynamicpdf/controllers/layouts/config_form.yaml new file mode 100644 index 0000000..1d26947 --- /dev/null +++ b/plugins/renatio/dynamicpdf/controllers/layouts/config_form.yaml @@ -0,0 +1,31 @@ +# =================================== +# Form Behavior Config +# =================================== + +# Record name +name: renatio.dynamicpdf::lang.layout.menu_label + +# Model Form Field configuration +form: $/renatio/dynamicpdf/models/layout/fields.yaml + +# Model Class name +modelClass: Renatio\DynamicPDF\Models\Layout + +# Default redirect location +defaultRedirect: renatio/dynamicpdf/templates/index/layouts + +# Create page +create: + title: renatio.dynamicpdf::lang.layout.create_layout + redirect: renatio/dynamicpdf/layouts/update/:id + redirectClose: renatio/dynamicpdf/templates/index/layouts + +# Update page +update: + title: renatio.dynamicpdf::lang.layout.edit_layout + redirect: renatio/dynamicpdf/templates/index/layouts + redirectClose: renatio/dynamicpdf/templates/index/layouts + +# Preview page +preview: + title: renatio.dynamicpdf::lang.templates.preview_html \ No newline at end of file diff --git a/plugins/renatio/dynamicpdf/controllers/layouts/create.php b/plugins/renatio/dynamicpdf/controllers/layouts/create.php new file mode 100644 index 0000000..a296829 --- /dev/null +++ b/plugins/renatio/dynamicpdf/controllers/layouts/create.php @@ -0,0 +1,58 @@ + + + + +fatalError) : ?> + 'layout']) ?> + +
+ formRender() ?> +
+ +
+
+ + + + + + + + + + +
+
+ + + +

fatalError) ?>

+

+ + + +

+ diff --git a/plugins/renatio/dynamicpdf/controllers/layouts/preview.php b/plugins/renatio/dynamicpdf/controllers/layouts/preview.php new file mode 100644 index 0000000..2411f2a --- /dev/null +++ b/plugins/renatio/dynamicpdf/controllers/layouts/preview.php @@ -0,0 +1,32 @@ + + + + +fatalError) : ?> +
+ +
+ +
+ + + +
+ +

fatalError) ?>

+

+ + + +

+ diff --git a/plugins/renatio/dynamicpdf/controllers/layouts/previewpdf.php b/plugins/renatio/dynamicpdf/controllers/layouts/previewpdf.php new file mode 100644 index 0000000..0648ef1 --- /dev/null +++ b/plugins/renatio/dynamicpdf/controllers/layouts/previewpdf.php @@ -0,0 +1,20 @@ + + + + +fatalError) : ?> +

fatalError) ?>

+

+ + + +

+ \ No newline at end of file diff --git a/plugins/renatio/dynamicpdf/controllers/layouts/update.php b/plugins/renatio/dynamicpdf/controllers/layouts/update.php new file mode 100644 index 0000000..16d80c9 --- /dev/null +++ b/plugins/renatio/dynamicpdf/controllers/layouts/update.php @@ -0,0 +1,86 @@ + + + + +fatalError) : ?> + 'layout']) ?> + +
+ formRender() ?> +
+ +
+
+ + + + + + + + + + + + + is_locked): ?> + + + + + + + + + + + +
+
+ + + +

fatalError) ?>

+

+ + + +

+ diff --git a/plugins/renatio/dynamicpdf/controllers/templates/_list_layouts_toolbar.php b/plugins/renatio/dynamicpdf/controllers/templates/_list_layouts_toolbar.php new file mode 100644 index 0000000..3233a26 --- /dev/null +++ b/plugins/renatio/dynamicpdf/controllers/templates/_list_layouts_toolbar.php @@ -0,0 +1,6 @@ +
+ + + +
\ No newline at end of file diff --git a/plugins/renatio/dynamicpdf/controllers/templates/_list_templates_toolbar.php b/plugins/renatio/dynamicpdf/controllers/templates/_list_templates_toolbar.php new file mode 100644 index 0000000..0c95d6a --- /dev/null +++ b/plugins/renatio/dynamicpdf/controllers/templates/_list_templates_toolbar.php @@ -0,0 +1,6 @@ +
+ + + +
\ No newline at end of file diff --git a/plugins/renatio/dynamicpdf/controllers/templates/config_form.yaml b/plugins/renatio/dynamicpdf/controllers/templates/config_form.yaml new file mode 100644 index 0000000..4b933d6 --- /dev/null +++ b/plugins/renatio/dynamicpdf/controllers/templates/config_form.yaml @@ -0,0 +1,31 @@ +# =================================== +# Form Behavior Config +# =================================== + +# Record name +name: renatio.dynamicpdf::lang.template.menu_label + +# Model Form Field configuration +form: $/renatio/dynamicpdf/models/template/fields.yaml + +# Model Class name +modelClass: Renatio\DynamicPDF\Models\Template + +# Default redirect location +defaultRedirect: renatio/dynamicpdf/templates + +# Create page +create: + title: renatio.dynamicpdf::lang.template.create_template + redirect: renatio/dynamicpdf/templates/update/:id + redirectClose: renatio/dynamicpdf/templates + +# Update page +update: + title: renatio.dynamicpdf::lang.template.edit_template + redirect: renatio/dynamicpdf/templates + redirectClose: renatio/dynamicpdf/templates + +# Preview page +preview: + title: renatio.dynamicpdf::lang.templates.preview_html \ No newline at end of file diff --git a/plugins/renatio/dynamicpdf/controllers/templates/config_layouts_list.yaml b/plugins/renatio/dynamicpdf/controllers/templates/config_layouts_list.yaml new file mode 100644 index 0000000..1353982 --- /dev/null +++ b/plugins/renatio/dynamicpdf/controllers/templates/config_layouts_list.yaml @@ -0,0 +1,44 @@ +# =================================== +# List Behavior Config +# =================================== + +# Model List Column configuration +list: $/renatio/dynamicpdf/models/layout/columns.yaml + +# Model Class name +modelClass: Renatio\DynamicPDF\Models\Layout + +# List Title +title: renatio.dynamicpdf::lang.layouts.label + +# Link URL for each record +recordUrl: renatio/dynamicpdf/layouts/update/:id + +# Message to display if the list is empty +noRecordsMessage: backend::lang.list.no_records + +# Records to display per page +recordsPerPage: 20 + +# Displays the list column set up button +showSetup: true + +# Displays the sorting link on each column +showSorting: true + +# Default sorting column +defaultSort: + column: created_at + direction: desc + +# Display checkboxes next to each record +showCheckboxes: false + +# Toolbar widget configuration +toolbar: + # Partial for toolbar buttons + buttons: list_layouts_toolbar + + # Search widget configuration + search: + prompt: backend::lang.list.search_prompt \ No newline at end of file diff --git a/plugins/renatio/dynamicpdf/controllers/templates/config_templates_list.yaml b/plugins/renatio/dynamicpdf/controllers/templates/config_templates_list.yaml new file mode 100644 index 0000000..5f38138 --- /dev/null +++ b/plugins/renatio/dynamicpdf/controllers/templates/config_templates_list.yaml @@ -0,0 +1,44 @@ +# =================================== +# List Behavior Config +# =================================== + +# Model List Column configuration +list: $/renatio/dynamicpdf/models/template/columns.yaml + +# Model Class name +modelClass: Renatio\DynamicPDF\Models\Template + +# List Title +title: renatio.dynamicpdf::lang.templates.label + +# Link URL for each record +recordUrl: renatio/dynamicpdf/templates/update/:id + +# Message to display if the list is empty +noRecordsMessage: backend::lang.list.no_records + +# Records to display per page +recordsPerPage: 20 + +# Displays the list column set up button +showSetup: true + +# Displays the sorting link on each column +showSorting: true + +# Default sorting column +defaultSort: + column: created_at + direction: desc + +# Display checkboxes next to each record +showCheckboxes: false + +# Toolbar widget configuration +toolbar: + # Partial for toolbar buttons + buttons: list_templates_toolbar + + # Search widget configuration + search: + prompt: backend::lang.list.search_prompt \ No newline at end of file diff --git a/plugins/renatio/dynamicpdf/controllers/templates/create.php b/plugins/renatio/dynamicpdf/controllers/templates/create.php new file mode 100644 index 0000000..63b1615 --- /dev/null +++ b/plugins/renatio/dynamicpdf/controllers/templates/create.php @@ -0,0 +1,58 @@ + + + + +fatalError) : ?> + 'layout']) ?> + +
+ formRender() ?> +
+ +
+
+ + + + + + + + + + +
+
+ + + +

fatalError) ?>

+

+ + + +

+ diff --git a/plugins/renatio/dynamicpdf/controllers/templates/index.php b/plugins/renatio/dynamicpdf/controllers/templates/index.php new file mode 100644 index 0000000..54f3e6a --- /dev/null +++ b/plugins/renatio/dynamicpdf/controllers/templates/index.php @@ -0,0 +1,25 @@ +
+ + +
+
+ listRender('templates') ?> +
+ +
+ listRender('layouts') ?> +
+
+
\ No newline at end of file diff --git a/plugins/renatio/dynamicpdf/controllers/templates/preview.php b/plugins/renatio/dynamicpdf/controllers/templates/preview.php new file mode 100644 index 0000000..c17e169 --- /dev/null +++ b/plugins/renatio/dynamicpdf/controllers/templates/preview.php @@ -0,0 +1,32 @@ + + + + +fatalError) : ?> +
+ +
+ +
+ + + +
+ +

fatalError) ?>

+

+ + + +

+ diff --git a/plugins/renatio/dynamicpdf/controllers/templates/previewpdf.php b/plugins/renatio/dynamicpdf/controllers/templates/previewpdf.php new file mode 100644 index 0000000..67a4e51 --- /dev/null +++ b/plugins/renatio/dynamicpdf/controllers/templates/previewpdf.php @@ -0,0 +1,20 @@ + + + + +fatalError) : ?> +

fatalError) ?>

+

+ + + +

+ \ No newline at end of file diff --git a/plugins/renatio/dynamicpdf/controllers/templates/update.php b/plugins/renatio/dynamicpdf/controllers/templates/update.php new file mode 100644 index 0000000..2d837ee --- /dev/null +++ b/plugins/renatio/dynamicpdf/controllers/templates/update.php @@ -0,0 +1,86 @@ + + + + +fatalError) : ?> + 'layout']) ?> + +
+ formRender() ?> +
+ +
+
+ + + + + + + + + + + + + getView()): ?> + + + + + + + + + + + +
+
+ + + +

fatalError) ?>

+

+ + + +

+ diff --git a/plugins/renatio/dynamicpdf/docs/banner.png b/plugins/renatio/dynamicpdf/docs/banner.png new file mode 100644 index 0000000..0bc9437 Binary files /dev/null and b/plugins/renatio/dynamicpdf/docs/banner.png differ diff --git a/plugins/renatio/dynamicpdf/docs/logo.png b/plugins/renatio/dynamicpdf/docs/logo.png new file mode 100644 index 0000000..3e619ac Binary files /dev/null and b/plugins/renatio/dynamicpdf/docs/logo.png differ diff --git a/plugins/renatio/dynamicpdf/docs/scr_1.png b/plugins/renatio/dynamicpdf/docs/scr_1.png new file mode 100644 index 0000000..8e9acca Binary files /dev/null and b/plugins/renatio/dynamicpdf/docs/scr_1.png differ diff --git a/plugins/renatio/dynamicpdf/docs/scr_2.png b/plugins/renatio/dynamicpdf/docs/scr_2.png new file mode 100644 index 0000000..11e4906 Binary files /dev/null and b/plugins/renatio/dynamicpdf/docs/scr_2.png differ diff --git a/plugins/renatio/dynamicpdf/docs/scr_3.png b/plugins/renatio/dynamicpdf/docs/scr_3.png new file mode 100644 index 0000000..3bac057 Binary files /dev/null and b/plugins/renatio/dynamicpdf/docs/scr_3.png differ diff --git a/plugins/renatio/dynamicpdf/docs/scr_4.png b/plugins/renatio/dynamicpdf/docs/scr_4.png new file mode 100644 index 0000000..f05c487 Binary files /dev/null and b/plugins/renatio/dynamicpdf/docs/scr_4.png differ diff --git a/plugins/renatio/dynamicpdf/docs/scr_5.png b/plugins/renatio/dynamicpdf/docs/scr_5.png new file mode 100644 index 0000000..bd48df4 Binary files /dev/null and b/plugins/renatio/dynamicpdf/docs/scr_5.png differ diff --git a/plugins/renatio/dynamicpdf/lang/cs/lang.php b/plugins/renatio/dynamicpdf/lang/cs/lang.php new file mode 100644 index 0000000..38e79b7 --- /dev/null +++ b/plugins/renatio/dynamicpdf/lang/cs/lang.php @@ -0,0 +1,54 @@ + [ + 'name' => 'Dynamické PDF', + 'description' => 'Generování dynamických a upravitelných PDF.', + ], + 'templates' => [ + 'label' => 'PDF Šablony', + 'code' => 'Kód', + 'title' => 'Nadpis', + 'description' => 'Popis', + 'layout' => 'Layout', + 'empty_option' => '-- Bez šablony --', + 'code_comment' => 'Unikátní kód patřící pouze této šabloně', + 'content_html' => 'HTML', + 'content_css' => 'CSS', + 'name' => 'Jméno', + 'return' => 'Zpět na seznam šablon', + 'new_template' => 'Nová šablona', + 'new_layout' => 'Nový layout', + 'templates' => 'Šablony', + 'layouts' => 'Layouty', + 'background_img' => 'Obrázek pozadí', + 'preview_pdf' => 'Náhled', + 'created_at' => 'Vytvořeno v', + 'updated_at' => 'Upraveno v', + 'background_img_comment' => 'Pro správné zobrazení použijte obrázek s 96 DPI' + ], + 'template' => [ + 'menu_label' => 'PDF Šablony', + 'create_template' => 'Vytvoření PDF šablony', + 'edit_template' => 'Úprava PDF šablony', + ], + 'layouts' => [ + 'label' => 'PDF Layouty', + 'return' => 'Zpět na seznam PDF layoutů', + ], + 'layout' => [ + 'menu_label' => 'PDF Layouty', + 'create_layout' => 'Vytvoření PDF layoutu', + 'edit_layout' => 'Úprava PDF layoutu', + ], + 'settings' => [ + 'description' => 'Správa PDF šablon a layoutů.', + ], + 'permissions' => [ + 'label' => 'Správa PDF šablon', + 'tab' => 'PDF', + ], + 'menu' => [ + 'label' => 'PDF' + ] +]; diff --git a/plugins/renatio/dynamicpdf/lang/de/lang.php b/plugins/renatio/dynamicpdf/lang/de/lang.php new file mode 100644 index 0000000..9c6af86 --- /dev/null +++ b/plugins/renatio/dynamicpdf/lang/de/lang.php @@ -0,0 +1,56 @@ + [ + 'name' => 'DynamicPDF', + 'description' => 'Generiert dynamische und anpassbare PDFs.', + ], + 'templates' => [ + 'label' => 'Vorlagen', + 'code' => 'Code', + 'title' => 'Titel', + 'description' => 'Beschreibung', + 'layout' => 'Layout', + 'empty_option' => '-- Kein Layout --', + 'code_comment' => 'Code wird verwendet um die Vorlage eindeutig zu Identifizieren.', + 'content_html' => 'HTML', + 'content_css' => 'CSS', + 'name' => 'Name', + 'return' => 'Zurück zu den PDF Vorlagen', + 'new_template' => 'Neue Vorlage', + 'new_layout' => 'Neues Layout', + 'templates' => 'Vorlagen', + 'layouts' => 'Layouts', + 'background_img' => 'Hintergrundbild', + 'preview_html' => 'HTML Vorschau', + 'preview_pdf' => 'PDF Vorschau', + 'created_at' => 'Erstellt am', + 'updated_at' => 'Aktualisiert am', + 'background_img_comment' => 'Bilder mit 96 DPI eignen sich am Besten', + ], + 'template' => [ + 'menu_label' => 'Vorlagen', + 'create_template' => 'Erstelle Vorlage', + 'edit_template' => 'Bearbeite Vorlage', + ], + 'layouts' => [ + 'label' => 'Layouts', + 'return' => 'Zurük zu den Layouts', + ], + 'layout' => [ + 'menu_label' => 'Layout', + 'create_layout' => 'Erstelle Layout', + 'edit_layout' => 'Bearbeite Layout', + ], + 'settings' => [ + 'description' => 'Verwaltung von Vorlagen und Layouts.', + ], + 'permissions' => [ + 'manage_templates' => 'Verwalte Vorlagen', + 'manage_layouts' => 'Verwalte Layouts', + 'tab' => 'PDF', + ], + 'menu' => [ + 'label' => 'PDF', + ], +]; diff --git a/plugins/renatio/dynamicpdf/lang/en/lang.php b/plugins/renatio/dynamicpdf/lang/en/lang.php new file mode 100644 index 0000000..664009e --- /dev/null +++ b/plugins/renatio/dynamicpdf/lang/en/lang.php @@ -0,0 +1,76 @@ + [ + 'name' => 'DynamicPDF', + 'description' => 'Generate dynamic and customized PDFs.', + ], + 'templates' => [ + 'label' => 'Templates', + 'code' => 'Code', + 'title' => 'Title', + 'description' => 'Description', + 'layout' => 'Layout', + 'empty_option' => '-- No layout --', + 'code_comment' => 'Unique code used to refer to this template', + 'content_html' => 'HTML', + 'content_css' => 'CSS/LESS', + 'name' => 'Name', + 'return' => 'Return to templates list', + 'new_template' => 'New Template', + 'new_layout' => 'New Layout', + 'templates' => 'Templates', + 'layouts' => 'Layouts', + 'background_img' => 'Background Image', + 'preview_html' => 'Preview HTML', + 'preview_pdf' => 'Preview PDF', + 'created_at' => 'Created at', + 'updated_at' => 'Updated at', + 'background_img_comment' => 'Use image with at least 96 DPI for correct display. Recommended 300 DPI.', + 'size' => 'Paper size', + 'orientation' => 'Paper orientation', + ], + 'template' => [ + 'menu_label' => 'Template', + 'create_template' => 'Create Template', + 'edit_template' => 'Edit Template', + 'not_found' => 'Unable to find a registered template with code', + ], + 'layouts' => [ + 'label' => 'Layouts', + 'return' => 'Return to layouts list', + ], + 'layout' => [ + 'menu_label' => 'Layout', + 'create_layout' => 'Create Layout', + 'edit_layout' => 'Edit Layout', + 'not_found' => 'Unable to find a registered layout with code', + ], + 'settings' => [ + 'description' => 'Manage templates and layouts.', + ], + 'permissions' => [ + 'manage_templates' => 'Manage templates', + 'manage_layouts' => 'Manage layouts', + 'tab' => 'PDF', + ], + 'menu' => [ + 'label' => 'PDF Templates', + 'category' => 'PDF', + 'description' => 'Modify the PDF templates and manage PDF layouts.', + ], + 'orientation' => [ + 'portrait' => 'Portrait', + 'landscape' => 'Landscape', + ], + 'options' => [ + 'empty' => '-- choose --', + ], + 'tab' => [ + 'options' => 'Options', + ], + 'demo' => [ + 'enabled' => 'Demo is enabled. Please refresh PDF templates list.', + 'disabled' => 'Demo is disabled. Please refresh PDF templates list.', + ], +]; diff --git a/plugins/renatio/dynamicpdf/lang/es-ar/lang.php b/plugins/renatio/dynamicpdf/lang/es-ar/lang.php new file mode 100644 index 0000000..121842d --- /dev/null +++ b/plugins/renatio/dynamicpdf/lang/es-ar/lang.php @@ -0,0 +1,54 @@ + [ + 'name' => 'DynamicPDF', + 'description' => 'Genera PDF dinámicos y personalizados.', + ], + 'templates' => [ + 'label' => 'Plantillas PDF', + 'code' => 'Código', + 'title' => 'Título', + 'description' => 'Descripción', + 'layout' => 'Diseño', + 'empty_option' => '-- Ningúno --', + 'code_comment' => 'Código único para hacer referencia a esta plantilla', + 'content_html' => 'HTML', + 'content_css' => 'CSS', + 'name' => 'Nombre', + 'return' => 'Volver a la lista de plantillas PDF', + 'new_template' => 'Nueva Plantilla', + 'new_layout' => 'Nuevo Diseño', + 'templates' => 'Plantillas', + 'layouts' => 'Diseños', + 'background_img' => 'Imagen de fondo', + 'preview_pdf' => 'Previsualizar', + 'created_at' => 'Creado en', + 'updated_at' => 'Modificado en', + 'background_img_comment' => 'Utilize una imagen de 96 DPI para una correcta visualización' + ], + 'template' => [ + 'menu_label' => 'Plantilla PDF', + 'create_template' => 'Crear Plantilla PDF', + 'edit_template' => 'Editar Plantilla PDF', + ], + 'layouts' => [ + 'label' => 'Diseños PDF', + 'return' => 'Volver la la lista de diseños PDF', + ], + 'layout' => [ + 'menu_label' => 'Diseño PDF', + 'create_layout' => 'Crear Diseño PDF', + 'edit_layout' => 'Editar Diseño PDF', + ], + 'settings' => [ + 'description' => 'Administrar plantillas y diseños PDF.', + ], + 'permissions' => [ + 'label' => 'Administrar plantillas PDF', + 'tab' => 'PDF', + ], + 'menu' => [ + 'label' => 'PDF' + ] +]; diff --git a/plugins/renatio/dynamicpdf/lang/es/lang.php b/plugins/renatio/dynamicpdf/lang/es/lang.php new file mode 100644 index 0000000..121842d --- /dev/null +++ b/plugins/renatio/dynamicpdf/lang/es/lang.php @@ -0,0 +1,54 @@ + [ + 'name' => 'DynamicPDF', + 'description' => 'Genera PDF dinámicos y personalizados.', + ], + 'templates' => [ + 'label' => 'Plantillas PDF', + 'code' => 'Código', + 'title' => 'Título', + 'description' => 'Descripción', + 'layout' => 'Diseño', + 'empty_option' => '-- Ningúno --', + 'code_comment' => 'Código único para hacer referencia a esta plantilla', + 'content_html' => 'HTML', + 'content_css' => 'CSS', + 'name' => 'Nombre', + 'return' => 'Volver a la lista de plantillas PDF', + 'new_template' => 'Nueva Plantilla', + 'new_layout' => 'Nuevo Diseño', + 'templates' => 'Plantillas', + 'layouts' => 'Diseños', + 'background_img' => 'Imagen de fondo', + 'preview_pdf' => 'Previsualizar', + 'created_at' => 'Creado en', + 'updated_at' => 'Modificado en', + 'background_img_comment' => 'Utilize una imagen de 96 DPI para una correcta visualización' + ], + 'template' => [ + 'menu_label' => 'Plantilla PDF', + 'create_template' => 'Crear Plantilla PDF', + 'edit_template' => 'Editar Plantilla PDF', + ], + 'layouts' => [ + 'label' => 'Diseños PDF', + 'return' => 'Volver la la lista de diseños PDF', + ], + 'layout' => [ + 'menu_label' => 'Diseño PDF', + 'create_layout' => 'Crear Diseño PDF', + 'edit_layout' => 'Editar Diseño PDF', + ], + 'settings' => [ + 'description' => 'Administrar plantillas y diseños PDF.', + ], + 'permissions' => [ + 'label' => 'Administrar plantillas PDF', + 'tab' => 'PDF', + ], + 'menu' => [ + 'label' => 'PDF' + ] +]; diff --git a/plugins/renatio/dynamicpdf/lang/hu/lang.php b/plugins/renatio/dynamicpdf/lang/hu/lang.php new file mode 100644 index 0000000..c6de1ed --- /dev/null +++ b/plugins/renatio/dynamicpdf/lang/hu/lang.php @@ -0,0 +1,65 @@ + [ + 'name' => 'Dinamikus PDF', + 'description' => 'Egyedi PDF fájlok generálása.', + ], + 'templates' => [ + 'label' => 'Sablonok', + 'code' => 'Kód', + 'title' => 'Cím', + 'description' => 'Leírás', + 'layout' => 'Elrendezés', + 'empty_option' => '-- nincs --', + 'code_comment' => 'Egyedi kódot adjon meg.', + 'content_html' => 'HTML', + 'content_css' => 'CSS', + 'name' => 'Név', + 'return' => 'Vissza a sablonokhoz', + 'new_template' => 'Új sablon', + 'new_layout' => 'Új elrendezés', + 'templates' => 'Sablonok', + 'layouts' => 'Elrendezések', + 'background_img' => 'Háttérkép', + 'preview_html' => 'HTML előnézet', + 'preview_pdf' => 'PDF előnézet', + 'created_at' => 'Létrehozva', + 'updated_at' => 'Módosítva', + 'background_img_comment' => 'A megfelelő megjelenéshez 96 DPI méretű képet használjon.', + 'size' => 'Papír mérete', + 'orientation' => 'Papír tájolása', + ], + 'template' => [ + 'menu_label' => 'Sablon', + 'create_template' => 'Sablon létrehozása', + 'edit_template' => 'Sablon szerkesztése', + ], + 'layouts' => [ + 'label' => 'Elrendezések', + 'return' => 'Vissza az elrendezésekhez', + ], + 'layout' => [ + 'menu_label' => 'Elrendezés', + 'create_layout' => 'Elrendezés létrehozása', + 'edit_layout' => 'Elrendezés szerkesztése', + ], + 'settings' => [ + 'description' => 'Sablonok és elrendezések kezelése.', + ], + 'permissions' => [ + 'manage_templates' => 'Sablonok kezelése', + 'manage_layouts' => 'Elrendezések kezelése', + 'tab' => 'PDF', + ], + 'menu' => [ + 'label' => 'PDF' + ], + 'orientation' => [ + 'portrait' => 'Álló', + 'landscape' => 'Fekvő', + ], + 'options' => [ + 'empty' => '-- válasszon --', + ], +]; diff --git a/plugins/renatio/dynamicpdf/lang/pl/lang.php b/plugins/renatio/dynamicpdf/lang/pl/lang.php new file mode 100644 index 0000000..663ade3 --- /dev/null +++ b/plugins/renatio/dynamicpdf/lang/pl/lang.php @@ -0,0 +1,70 @@ + [ + 'name' => 'DynamicPDF', + 'description' => 'Generuj dynamiczne pliki PDF.', + ], + 'templates' => [ + 'label' => 'Szablony', + 'code' => 'Kod', + 'title' => 'Tytuł', + 'description' => 'Opis', + 'layout' => 'Układ', + 'empty_option' => '-- Brak układu --', + 'code_comment' => 'Unikalny kod powiązany z tym szablonem', + 'content_html' => 'HTML', + 'content_css' => 'CSS/LESS', + 'name' => 'Nazwa', + 'return' => 'Powrót do listy szablonów', + 'new_template' => 'Nowy szablon', + 'new_layout' => 'Nowy układ', + 'templates' => 'Szablony', + 'layouts' => 'Układy', + 'background_img' => 'Obraz w tle', + 'preview_html' => 'Podgląd HTML', + 'preview_pdf' => 'Podgląd PDF', + 'created_at' => 'Data utworzenia', + 'updated_at' => 'Data edycji', + 'background_img_comment' => 'Użyj obrazu o rozdzielczości przynajmniej 96 DPI do poprawnego wyświetlenia. Zalecany obraz 300 DPI.', + 'size' => 'Rozmiar papieru', + 'orientation' => 'Orientacja papieru', + ], + 'template' => [ + 'menu_label' => 'Szablon', + 'create_template' => 'Utwórz szablon', + 'edit_template' => 'Edycja szablonu', + ], + 'layouts' => [ + 'label' => 'Układu', + 'return' => 'Powrót do listy układów', + ], + 'layout' => [ + 'menu_label' => 'Układ', + 'create_layout' => 'Utwórz układ', + 'edit_layout' => 'Edycja układu', + ], + 'settings' => [ + 'description' => 'Zarządzaj szablonami i układami.', + ], + 'permissions' => [ + 'manage_templates' => 'Zarządzaj szablonami', + 'manage_layouts' => 'Zarządzaj układami', + 'tab' => 'PDF', + ], + 'menu' => [ + 'label' => 'Szablony PDF', + 'category' => 'PDF', + 'description' => 'Modyfikuj szablony i układy PDF.', + ], + 'orientation' => [ + 'portrait' => 'Pionowy', + 'landscape' => 'Poziomy', + ], + 'options' => [ + 'empty' => '-- wybierz --', + ], + 'tab' => [ + 'options' => 'Opcje', + ], +]; diff --git a/plugins/renatio/dynamicpdf/lang/pt-br/lang.php b/plugins/renatio/dynamicpdf/lang/pt-br/lang.php new file mode 100644 index 0000000..5d64093 --- /dev/null +++ b/plugins/renatio/dynamicpdf/lang/pt-br/lang.php @@ -0,0 +1,76 @@ + [ + 'name' => 'DynamicPDF', + 'description' => 'Gere PDFs dinâmicos e personalizados.', + ], + 'templates' => [ + 'label' => 'Modelos', + 'code' => 'Código', + 'title' => 'Título', + 'description' => 'Descrição', + 'layout' => 'Modelo', + 'empty_option' => '-- Sem modelo --', + 'code_comment' => 'Código exclusivo usado para se referir a este modelo', + 'content_html' => 'HTML', + 'content_css' => 'CSS/LESS', + 'name' => 'Nome', + 'return' => 'Voltar à lista de modelos', + 'new_template' => 'Novo modelo', + 'new_layout' => 'Novo Layout', + 'templates' => 'Modelos', + 'layouts' => 'Layouts', + 'background_img' => 'Imagem de fundo', + 'preview_html' => 'Pré-visualizar HTML', + 'preview_pdf' => 'Pré-visualizar PDF', + 'created_at' => 'Criado em', + 'updated_at' => 'Atualizado em', + 'background_img_comment' => 'Use imagem com pelo menos 96 DPI para exibição correta. Recomendado 300 de DPI.', + 'size' => 'Tamanho do papel', + 'orientation' => 'Orientação do papel', + ], + 'template' => [ + 'menu_label' => 'Modelo', + 'create_template' => 'Criar Modelo', + 'edit_template' => 'Editar Modelo', + 'not_found' => 'Incapaz de encontrar um modelo registrado com código', + ], + 'layouts' => [ + 'label' => 'Layouts', + 'return' => 'Voltar à lista de layouts', + ], + 'layout' => [ + 'menu_label' => 'Layout', + 'create_layout' => 'Criar Layout', + 'edit_layout' => 'Editar Layout', + 'not_found' => 'Incapaz de encontrar um layout registrado com código', + ], + 'settings' => [ + 'description' => 'Gerencie modelos e layouts.', + ], + 'permissions' => [ + 'manage_templates' => 'Gerencie modelos', + 'manage_layouts' => 'Gerencie layouts', + 'tab' => 'PDF', + ], + 'menu' => [ + 'label' => 'Modelos PDF', + 'category' => 'PDF', + 'description' => 'Modifique os modelos de PDF e gerencie layouts de PDF.', + ], + 'orientation' => [ + 'portrait' => 'Retrato', + 'landscape' => 'Paisagem', + ], + 'options' => [ + 'empty' => '-- escolha --', + ], + 'tab' => [ + 'options' => 'Opções', + ], + 'demo' => [ + 'enabled' => 'A demonstração está ativada. Atualize a lista de modelos de PDF.', + 'disabled' => 'A demonstração está desativada. Atualize a lista de modelos de PDF.', + ], +]; diff --git a/plugins/renatio/dynamicpdf/models/Layout.php b/plugins/renatio/dynamicpdf/models/Layout.php new file mode 100644 index 0000000..f26e383 --- /dev/null +++ b/plugins/renatio/dynamicpdf/models/Layout.php @@ -0,0 +1,69 @@ + ['required'], + 'code' => ['required', 'unique:renatio_dynamicpdf_pdf_layouts'], + 'content_html' => ['required'], + ]; + + public $attachOne = [ + 'background_img' => File::class, + ]; + + public function getHtmlAttribute() + { + return PDF::loadLayout($this->code)->getDompdf()->output_html(); + } + + public static function byCode($code) + { + return static::whereCode($code)->firstOrFail(); + } + + public function getCSS() + { + $parser = new Less_Parser; + + return $parser->parse($this->content_css)->getCss(); + } + + public function fillFromCode() + { + if (! ($path = $this->getView())) { + throw new ApplicationException(e(trans('renatio.dynamicpdf::lang.layout.not_found')).': '.$this->code); + } + + $this->fillFromView($path); + } + + public function fillFromView($path) + { + $sections = PDFParser::sections($path); + + $this->name = array_get($sections, 'settings.name', '???'); + $this->content_css = array_get($sections, 'css'); + $this->content_html = array_get($sections, 'html'); + } + + public function getView() + { + return array_get(PDFManager::instance()->listRegisteredLayouts(), $this->code); + } +} diff --git a/plugins/renatio/dynamicpdf/models/Template.php b/plugins/renatio/dynamicpdf/models/Template.php new file mode 100644 index 0000000..fff5b71 --- /dev/null +++ b/plugins/renatio/dynamicpdf/models/Template.php @@ -0,0 +1,87 @@ + Layout::class, + ]; + + public $rules = [ + 'title' => ['required'], + 'code' => ['required', 'unique:renatio_dynamicpdf_pdf_templates'], + 'content_html' => ['required'], + ]; + + public function afterFetch() + { + if (! $this->is_custom) { + $this->fillFromView($this->code); + } + } + + public function fillFromCode() + { + if (! ($path = $this->getView())) { + throw new ApplicationException(e(trans('renatio.dynamicpdf::lang.template.not_found')).': '.$this->code); + } + + $this->fillFromView($path); + } + + public function fillFromView($path) + { + $sections = PDFParser::sections($path); + + $this->title = array_get($sections, 'settings.title', '???'); + $this->code = $path; + $this->layout = Layout::whereCode(array_get($sections, 'settings.layout'))->first(); + $this->size = array_get($sections, 'settings.size'); + $this->orientation = array_get($sections, 'settings.orientation'); + $this->description = array_get($sections, 'settings.description'); + $this->content_html = array_get($sections, 'html'); + } + + public function getHtmlAttribute() + { + return PDF::loadTemplate($this->code)->getDompdf()->output_html(); + } + + public static function byCode($code) + { + return static::whereCode($code)->firstOrFail(); + } + + public static function getSizeOptions() + { + $sizes = array_keys(CPDF::$PAPER_SIZES); + + return array_combine($sizes, $sizes); + } + + public static function getOrientationOptions() + { + return [ + 'portrait' => 'renatio.dynamicpdf::lang.orientation.portrait', + 'landscape' => 'renatio.dynamicpdf::lang.orientation.landscape', + ]; + } + + public function getView() + { + return array_get(PDFManager::instance()->listRegisteredTemplates(), $this->code); + } +} diff --git a/plugins/renatio/dynamicpdf/models/layout/columns.yaml b/plugins/renatio/dynamicpdf/models/layout/columns.yaml new file mode 100644 index 0000000..87c7278 --- /dev/null +++ b/plugins/renatio/dynamicpdf/models/layout/columns.yaml @@ -0,0 +1,21 @@ +# =================================== +# Column Definitions +# =================================== + +columns: + + name: + label: renatio.dynamicpdf::lang.templates.name + searchable: true + + code: + label: renatio.dynamicpdf::lang.templates.code + searchable: true + + created_at: + label: renatio.dynamicpdf::lang.templates.created_at + type: datetime + + updated_at: + label: renatio.dynamicpdf::lang.templates.updated_at + type: datetime \ No newline at end of file diff --git a/plugins/renatio/dynamicpdf/models/layout/fields.yaml b/plugins/renatio/dynamicpdf/models/layout/fields.yaml new file mode 100644 index 0000000..ea6c663 --- /dev/null +++ b/plugins/renatio/dynamicpdf/models/layout/fields.yaml @@ -0,0 +1,60 @@ +# =================================== +# Field Definitions +# =================================== + +fields: + + name@create: + label: renatio.dynamicpdf::lang.templates.name + span: left + + name@update: + label: renatio.dynamicpdf::lang.templates.name + span: full + + code@create: + label: renatio.dynamicpdf::lang.templates.code + comment: renatio.dynamicpdf::lang.templates.code_comment + preset: name + span: right + +secondaryTabs: + + fields: + + content_html: + type: codeeditor + size: giant + tab: renatio.dynamicpdf::lang.templates.content_html + language: html + stretch: true + default: | + + + + + Document + + + + {{ content_html|raw }} + + + + content_css: + tab: renatio.dynamicpdf::lang.templates.content_css + type: codeeditor + size: giant + language: css + stretch: true + + background_img: + label: renatio.dynamicpdf::lang.templates.background_img + tab: renatio.dynamicpdf::lang.tab.options + type: fileupload + mode: image + comment: renatio.dynamicpdf::lang.templates.background_img_comment + attachOnUpload: true + span: left diff --git a/plugins/renatio/dynamicpdf/models/template/columns.yaml b/plugins/renatio/dynamicpdf/models/template/columns.yaml new file mode 100644 index 0000000..bf7767d --- /dev/null +++ b/plugins/renatio/dynamicpdf/models/template/columns.yaml @@ -0,0 +1,30 @@ +# =================================== +# Column Definitions +# =================================== + +columns: + + title: + label: renatio.dynamicpdf::lang.templates.name + searchable: true + + code: + label: renatio.dynamicpdf::lang.templates.code + searchable: true + + description: + label: renatio.dynamicpdf::lang.templates.description + searchable: true + + layout: + label: renatio.dynamicpdf::lang.templates.layout + relation: layout + select: name + + created_at: + label: renatio.dynamicpdf::lang.templates.created_at + type: datetime + + updated_at: + label: renatio.dynamicpdf::lang.templates.updated_at + type: datetime diff --git a/plugins/renatio/dynamicpdf/models/template/fields.yaml b/plugins/renatio/dynamicpdf/models/template/fields.yaml new file mode 100644 index 0000000..466c04d --- /dev/null +++ b/plugins/renatio/dynamicpdf/models/template/fields.yaml @@ -0,0 +1,52 @@ +# =================================== +# Field Definitions +# =================================== + +fields: + + title: + label: renatio.dynamicpdf::lang.templates.title + span: left + + code@create: + label: renatio.dynamicpdf::lang.templates.code + comment: renatio.dynamicpdf::lang.templates.code_comment + preset: title + span: right + + layout: + label: renatio.dynamicpdf::lang.templates.layout + type: relation + emptyOption: renatio.dynamicpdf::lang.templates.empty_option + span: auto + + description: + label: renatio.dynamicpdf::lang.templates.description + tab: renatio.dynamicpdf::lang.tab.options + type: textarea + size: tiny + +secondaryTabs: + + fields: + + content_html: + type: codeeditor + size: giant + tab: renatio.dynamicpdf::lang.templates.content_html + language: html + stretch: true + + size: + label: renatio.dynamicpdf::lang.templates.size + tab: renatio.dynamicpdf::lang.tab.options + type: dropdown + emptyOption: renatio.dynamicpdf::lang.options.empty + span: left + + orientation: + label: renatio.dynamicpdf::lang.templates.orientation + tab: renatio.dynamicpdf::lang.tab.options + type: dropdown + emptyOption: renatio.dynamicpdf::lang.options.empty + span: right \ No newline at end of file diff --git a/plugins/renatio/dynamicpdf/updates/add_is_custom_to_templates_table.php b/plugins/renatio/dynamicpdf/updates/add_is_custom_to_templates_table.php new file mode 100644 index 0000000..338466f --- /dev/null +++ b/plugins/renatio/dynamicpdf/updates/add_is_custom_to_templates_table.php @@ -0,0 +1,24 @@ +boolean('is_custom')->default(false); + }); + } + + public function down() + { + Schema::table('renatio_dynamicpdf_pdf_templates', function (Blueprint $table) { + $table->dropColumn('is_custom'); + }); + } +} diff --git a/plugins/renatio/dynamicpdf/updates/add_is_locked_to_layouts_table.php b/plugins/renatio/dynamicpdf/updates/add_is_locked_to_layouts_table.php new file mode 100644 index 0000000..cf1c4e3 --- /dev/null +++ b/plugins/renatio/dynamicpdf/updates/add_is_locked_to_layouts_table.php @@ -0,0 +1,24 @@ +boolean('is_locked')->default(false); + }); + } + + public function down() + { + Schema::table('renatio_dynamicpdf_pdf_layouts', function (Blueprint $table) { + $table->dropColumn('is_locked'); + }); + } +} diff --git a/plugins/renatio/dynamicpdf/updates/add_paper_configuration_to_templates_table.php b/plugins/renatio/dynamicpdf/updates/add_paper_configuration_to_templates_table.php new file mode 100644 index 0000000..bce116f --- /dev/null +++ b/plugins/renatio/dynamicpdf/updates/add_paper_configuration_to_templates_table.php @@ -0,0 +1,25 @@ +string('size')->nullable(); + $table->string('orientation')->nullable(); + }); + } + + public function down() + { + Schema::table('renatio_dynamicpdf_pdf_templates', function (Blueprint $table) { + $table->dropColumn(['size', 'orientation']); + }); + } +} diff --git a/plugins/renatio/dynamicpdf/updates/create_pdf_layouts_table.php b/plugins/renatio/dynamicpdf/updates/create_pdf_layouts_table.php new file mode 100644 index 0000000..975bd4a --- /dev/null +++ b/plugins/renatio/dynamicpdf/updates/create_pdf_layouts_table.php @@ -0,0 +1,27 @@ +increments('id'); + $table->string('code')->index(); + $table->string('name'); + $table->text('content_html')->nullable(); + $table->text('content_css')->nullable(); + $table->timestamps(); + }); + } + + public function down() + { + Schema::dropIfExists('renatio_dynamicpdf_pdf_layouts'); + } +} diff --git a/plugins/renatio/dynamicpdf/updates/create_pdf_templates_table.php b/plugins/renatio/dynamicpdf/updates/create_pdf_templates_table.php new file mode 100644 index 0000000..92248c5 --- /dev/null +++ b/plugins/renatio/dynamicpdf/updates/create_pdf_templates_table.php @@ -0,0 +1,28 @@ +increments('id'); + $table->unsignedInteger('layout_id')->index()->nullable(); + $table->string('code')->index(); + $table->string('title'); + $table->text('description')->nullable(); + $table->text('content_html')->nullable(); + $table->timestamps(); + }); + } + + public function down() + { + Schema::dropIfExists('renatio_dynamicpdf_pdf_templates'); + } +} diff --git a/plugins/renatio/dynamicpdf/updates/fix_custom_templates_error.php b/plugins/renatio/dynamicpdf/updates/fix_custom_templates_error.php new file mode 100644 index 0000000..897aca2 --- /dev/null +++ b/plugins/renatio/dynamicpdf/updates/fix_custom_templates_error.php @@ -0,0 +1,20 @@ +update(['is_custom' => 1]); + } + + public function down() + { + // + } +} diff --git a/plugins/renatio/dynamicpdf/updates/version.yaml b/plugins/renatio/dynamicpdf/updates/version.yaml new file mode 100644 index 0000000..65db001 --- /dev/null +++ b/plugins/renatio/dynamicpdf/updates/version.yaml @@ -0,0 +1,48 @@ +1.0.1: + - Initialize plugin. + - create_pdf_layouts_table.php + - create_pdf_templates_table.php +1.0.2: Minor changes. +1.1.0: Important update. +1.1.1: Use Twig::parse() facade. Only update for October build 300 and above. +1.1.2: Minor changes. +1.1.3: Add stream parameters and Czech locale. Thanks to @vojtasvoboda. +1.1.4: Add Spanish and Spanish-Argentina locale. Thanks to @kocholes. +1.1.5: UI improvements. Thanks to @kocholes. +2.0.0: This is an important update that contains breaking changes. +2.0.1: Add preview HTML buttons. +2.1.0: This is an important update that contains breaking changes. +2.1.1: Upgrade to DOMPDF 0.7. +2.1.2: Database maintenance. Updated all timestamp columns to be nullable. +2.1.3: Upgrade to DOMPDF 0.8. +2.1.4: German language. Thanks to @TimFoerster. +2.1.5: Fix open_basedir restriction on some hostings. Set isRemoteEnabled flag to allow absolute paths. +2.1.6: Allow Laravel 5.5. +3.0.0: Add support for Laravel 5.5. +3.0.1: Add support for RainLab.Translate plugin. +3.0.2: Fix creating fonts directory. +3.0.3: Allow to use CMS partials and filters. +3.0.4: + - Add paper size and orientation configuration. + - add_paper_configuration_to_templates_table.php +3.0.5: Support LESS in PDF layouts. +4.0.0: Require PHP 7.1. Please see upgrade guide before update. +4.0.1: Fix error when active theme is not set. +4.0.2: + - Allow to register mail templates and layouts. + - add_is_custom_to_templates_table.php + - add_is_locked_to_layouts_table.php +4.0.3: + - Fix custom templates error. + - fix_custom_templates_error.php +4.0.4: Fix composer installation. +4.0.5: Fix custom template error. +4.0.6: Allow to reset view template to default. +4.0.7: Add Polish translation. +4.0.8: Allow to set dompdf option with dynamic method. +5.0.1: Support October v2.0 and upgrade to DOMPDF 1.0. +5.0.2: Add demo console command. +5.0.3: Update documentation. +5.0.4: Fix preview pdf layout. +5.0.5: Brazilian portuguese language. Thanks to @gcairesdev. +6.0.0: Require October CMS 3.0. diff --git a/plugins/renatio/dynamicpdf/views/pdf/header_and_footer.htm b/plugins/renatio/dynamicpdf/views/pdf/header_and_footer.htm new file mode 100644 index 0000000..e0fbb4a --- /dev/null +++ b/plugins/renatio/dynamicpdf/views/pdf/header_and_footer.htm @@ -0,0 +1,35 @@ +title = "Header and Footer" +description = "Example use of header & footer, page break, page numbers and full background image" +layout = "renatio.dynamicpdf::pdf.layouts.header_and_footer" +== +
+

Example Header

+ +

Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.

+ +

Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.

+ +

Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.

+ +

Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.

+ +

Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.

+ +

Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.

+ +

Page break here!!!

+ +
+ +
+ +

Example Header

+ +

Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.

+ +

Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.

+ +

Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.

+ +

Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.

+
diff --git a/plugins/renatio/dynamicpdf/views/pdf/invoice.htm b/plugins/renatio/dynamicpdf/views/pdf/invoice.htm new file mode 100644 index 0000000..20e059a --- /dev/null +++ b/plugins/renatio/dynamicpdf/views/pdf/invoice.htm @@ -0,0 +1,104 @@ +title = "Invoice" +description = "Example invoice with custom font and image embed" +layout = "renatio.dynamicpdf::pdf.layouts.default" +== +
+

TablePlus

+ +

via Paddle.com

+ +
+

Invoice

+
+ +
+

Invoice to

+ +

John Doe

+ +

+ Example street 16
+ Warszawa, 50-100
+ Poland +

+ +

VAT Number: PL2332213309

+
+ +
+

Invoice from

+ +

Paddle.com Market Ltd

+ +

+ Judd House 18-29 Mora Street
+ London, EC1V 8BT
+ United Kingdom +

+ +

VAT Number: EU372017215

+ +

Company Number: 08172165

+
+ +
+ +

Your order

+ +
+

Customer: michal.plodowski@gmail.com

+

Order Number / Invoice: #28542217

+

Billing date: 01 Sep 2020

+
+ +
+

Payment method: Visa card ending 2222

+

Currency: USD

+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ProductQuantityPrice
TablePlus License Renewal1US$39.00
VAT (0%)US$0.00
YOUR ORDERUS$39.00
+ No VAT - Supply may be subject to reverse charge in the country of receipt +
+ +

+ The US$39.00 payment will appear on your bank/card statement as: + PADDLE.NET* TABLEPLUS +

+ +

+ If you have a problem with your order (e.g. don’t recognise the charge, suspect a fraudulent transaction), please visit paddle.net. +

+ +

+
diff --git a/plugins/renatio/dynamicpdf/views/pdf/layouts/default.htm b/plugins/renatio/dynamicpdf/views/pdf/layouts/default.htm new file mode 100644 index 0000000..8d709c0 --- /dev/null +++ b/plugins/renatio/dynamicpdf/views/pdf/layouts/default.htm @@ -0,0 +1,47 @@ +name = "Default Layout" +== + + + + + Default + + + + + {{ content_html|raw }} + + diff --git a/plugins/renatio/dynamicpdf/views/pdf/layouts/header_and_footer.htm b/plugins/renatio/dynamicpdf/views/pdf/layouts/header_and_footer.htm new file mode 100644 index 0000000..e8eca65 --- /dev/null +++ b/plugins/renatio/dynamicpdf/views/pdf/layouts/header_and_footer.htm @@ -0,0 +1,86 @@ +name = "Header and Footer" +== + + + + + Header and Footer + + + + + + +
+ This is example header text +
+ +
+ This is example footer text +
+ + {{ content_html|raw }} + +