├── .gitignore ├── LICENSE ├── README.md ├── composer.json ├── composer.lock ├── config └── poster.php └── src ├── Filesystem.php ├── Http ├── Controllers │ └── PosterController.php ├── Middleware │ └── GuardRenderURI.php └── routes.php ├── PosterGenerator.php ├── PosterInterface.php ├── PosterResponse.php └── Providers └── PosterGeneratorServiceProvider.php /.gitignore: -------------------------------------------------------------------------------- 1 | vendor -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Just 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Laravel poster generator 2 | NOTE: Package is still in development, use it at your own cause 3 | 4 | This collection of classes will enable you to generate `posters` quickly using `PhantomJS`. It enables the developer to easiliy implement an poster in HTML/CSS/JavaScript and let PhantomJS capture this into a image or PDF. 5 | 6 | ## Installation 7 | First please add the following in your `composer.json` file 8 | ```json 9 | "scripts": { 10 | "post-install-cmd": [ 11 | "PhantomInstaller\\Installer::installPhantomJS" 12 | ], 13 | "post-update-cmd": [ 14 | "PhantomInstaller\\Installer::installPhantomJS" 15 | ] 16 | }, 17 | ``` 18 | And require the postergenerator in your project 19 | ```bash 20 | composer require wearejust/laravel-postergenerator 21 | ``` 22 | ```php 23 | // app.php 24 | 25 | ... 26 | Just\PosterGenerator\Providers\PosterGeneratorServiceProvider::class 27 | ... 28 | ``` 29 | ## Configuration 30 | You can adjust the settings in the config file (`config/poster.php`). You can also publish the config file using the artisan publish command 31 | 32 | ## Usage 33 | Firstly, create an poster object with the properties you need in your poster. This could things from `text` to `images`. It's important to implement the `Just\PosterGenerator\PosterInterface`, for example: 34 | 35 | ```php 36 | background = $background; 63 | $this->text = $text; 64 | } 65 | 66 | /** 67 | * Returns a set of variables that are available to the view 68 | * 69 | * @return array 70 | */ 71 | public function getProperties() 72 | { 73 | return [ 74 | 'background' => $this->getImage(), 75 | 'text' => $this->getText() 76 | ]; 77 | } 78 | 79 | /** 80 | * @return string 81 | */ 82 | private function getText() 83 | { 84 | return strtoupper($this->text); 85 | } 86 | 87 | /** 88 | * @return string 89 | */ 90 | private function getImage() 91 | { 92 | // Could you Croppa (https://github.com/BKWLD/croppa) to crop image and convert it to string (path) 93 | return Croppa::url($this->background->getFilename(), 595,842, ['resize']); 94 | } 95 | 96 | /** 97 | * Returns full path (blade) to your view. The arguments of 98 | * getProperties() will be auto inserted 99 | * in to this view 100 | * 101 | * @return string 102 | */ 103 | public function getTemplatePath() 104 | { 105 | return 'path.to.your.html.poster'; 106 | } 107 | 108 | /** 109 | * Returns width/height of the poster 110 | * 111 | * @return array 112 | */ 113 | public function getViewportSize() 114 | { 115 | return [595, 842]; 116 | } 117 | } 118 | ``` 119 | Now that you have your poster object, it's quite easy to generate it via the `Just\PosterGenerator\PosterGenerator` class 120 | ```php 121 | generator->generatePDF($poster); 127 | 128 | // Or we could generate an Image 129 | $response = $this->generator->generateImage($poster, 'jpg'); 130 | 131 | // In the $response we have the original response (getResponse()) out of Phantom 132 | // and an getFile() method to get the generated file. 133 | if ($response->getResponse()->getStatus() === 200) { 134 | return [ 135 | 'status' => 'success', 136 | 'url' => $response->getFile()->getFilename()) 137 | ]; 138 | } 139 | 140 | return [ 141 | 'status' => 'error' 142 | ]; 143 | ``` 144 | 145 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wearejust/laravel-postergenerator", 3 | "license": "MIT", 4 | "authors": [ 5 | { 6 | "name": "Cees van Egmond", 7 | "email": "cees.vanegmond@wearejust.com" 8 | } 9 | ], 10 | "require": { 11 | "php": ">=5.5.9", 12 | "jakoch/phantomjs-installer": "2.1.1", 13 | "jonnyw/php-phantomjs": "4.*", 14 | "illuminate/support": "^5" 15 | }, 16 | "autoload": { 17 | "psr-4": { 18 | "Just\\PosterGenerator\\": "src/" 19 | } 20 | }, 21 | "config": { 22 | "preferred-install": "dist", 23 | "bin-dir": "bin" 24 | }, 25 | "post-install-cmd": [ 26 | "PhantomInstaller\\Installer::installPhantomJS" 27 | ], 28 | "post-update-cmd": [ 29 | "PhantomInstaller\\Installer::installPhantomJS" 30 | ], 31 | "minimum-stability": "dev", 32 | "prefer-stable": true 33 | } 34 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", 5 | "This file is @generated automatically" 6 | ], 7 | "hash": "7846fc71a41e510109f1b67900dc8632", 8 | "content-hash": "590de9337a114d542867d001e7f25ed8", 9 | "packages": [ 10 | { 11 | "name": "doctrine/inflector", 12 | "version": "v1.1.0", 13 | "source": { 14 | "type": "git", 15 | "url": "https://github.com/doctrine/inflector.git", 16 | "reference": "90b2128806bfde671b6952ab8bea493942c1fdae" 17 | }, 18 | "dist": { 19 | "type": "zip", 20 | "url": "https://api.github.com/repos/doctrine/inflector/zipball/90b2128806bfde671b6952ab8bea493942c1fdae", 21 | "reference": "90b2128806bfde671b6952ab8bea493942c1fdae", 22 | "shasum": "" 23 | }, 24 | "require": { 25 | "php": ">=5.3.2" 26 | }, 27 | "require-dev": { 28 | "phpunit/phpunit": "4.*" 29 | }, 30 | "type": "library", 31 | "extra": { 32 | "branch-alias": { 33 | "dev-master": "1.1.x-dev" 34 | } 35 | }, 36 | "autoload": { 37 | "psr-0": { 38 | "Doctrine\\Common\\Inflector\\": "lib/" 39 | } 40 | }, 41 | "notification-url": "https://packagist.org/downloads/", 42 | "license": [ 43 | "MIT" 44 | ], 45 | "authors": [ 46 | { 47 | "name": "Roman Borschel", 48 | "email": "roman@code-factory.org" 49 | }, 50 | { 51 | "name": "Benjamin Eberlei", 52 | "email": "kontakt@beberlei.de" 53 | }, 54 | { 55 | "name": "Guilherme Blanco", 56 | "email": "guilhermeblanco@gmail.com" 57 | }, 58 | { 59 | "name": "Jonathan Wage", 60 | "email": "jonwage@gmail.com" 61 | }, 62 | { 63 | "name": "Johannes Schmitt", 64 | "email": "schmittjoh@gmail.com" 65 | } 66 | ], 67 | "description": "Common String Manipulations with regard to casing and singular/plural rules.", 68 | "homepage": "http://www.doctrine-project.org", 69 | "keywords": [ 70 | "inflection", 71 | "pluralize", 72 | "singularize", 73 | "string" 74 | ], 75 | "time": "2015-11-06 14:35:42" 76 | }, 77 | { 78 | "name": "illuminate/contracts", 79 | "version": "v5.2.19", 80 | "source": { 81 | "type": "git", 82 | "url": "https://github.com/illuminate/contracts.git", 83 | "reference": "511a6798e097666b95c6ef3f339e386cc006feba" 84 | }, 85 | "dist": { 86 | "type": "zip", 87 | "url": "https://api.github.com/repos/illuminate/contracts/zipball/511a6798e097666b95c6ef3f339e386cc006feba", 88 | "reference": "511a6798e097666b95c6ef3f339e386cc006feba", 89 | "shasum": "" 90 | }, 91 | "require": { 92 | "php": ">=5.5.9" 93 | }, 94 | "type": "library", 95 | "extra": { 96 | "branch-alias": { 97 | "dev-master": "5.2-dev" 98 | } 99 | }, 100 | "autoload": { 101 | "psr-4": { 102 | "Illuminate\\Contracts\\": "" 103 | } 104 | }, 105 | "notification-url": "https://packagist.org/downloads/", 106 | "license": [ 107 | "MIT" 108 | ], 109 | "authors": [ 110 | { 111 | "name": "Taylor Otwell", 112 | "email": "taylorotwell@gmail.com" 113 | } 114 | ], 115 | "description": "The Illuminate Contracts package.", 116 | "homepage": "http://laravel.com", 117 | "time": "2016-01-07 19:57:38" 118 | }, 119 | { 120 | "name": "illuminate/support", 121 | "version": "v5.2.19", 122 | "source": { 123 | "type": "git", 124 | "url": "https://github.com/illuminate/support.git", 125 | "reference": "6443a072215137161dcfc56385af95dd6eceaaad" 126 | }, 127 | "dist": { 128 | "type": "zip", 129 | "url": "https://api.github.com/repos/illuminate/support/zipball/6443a072215137161dcfc56385af95dd6eceaaad", 130 | "reference": "6443a072215137161dcfc56385af95dd6eceaaad", 131 | "shasum": "" 132 | }, 133 | "require": { 134 | "doctrine/inflector": "~1.0", 135 | "ext-mbstring": "*", 136 | "illuminate/contracts": "5.2.*", 137 | "php": ">=5.5.9" 138 | }, 139 | "suggest": { 140 | "illuminate/filesystem": "Required to use the composer class (5.2.*).", 141 | "jeremeamia/superclosure": "Required to be able to serialize closures (~2.2).", 142 | "paragonie/random_compat": "Provides a compatible interface like PHP7's random_bytes() in PHP 5 projects (~1.1).", 143 | "symfony/polyfill-php56": "Required to use the hash_equals function on PHP 5.5 (~1.0).", 144 | "symfony/process": "Required to use the composer class (2.8.*|3.0.*).", 145 | "symfony/var-dumper": "Improves the dd function (2.8.*|3.0.*)." 146 | }, 147 | "type": "library", 148 | "extra": { 149 | "branch-alias": { 150 | "dev-master": "5.2-dev" 151 | } 152 | }, 153 | "autoload": { 154 | "psr-4": { 155 | "Illuminate\\Support\\": "" 156 | }, 157 | "files": [ 158 | "helpers.php" 159 | ] 160 | }, 161 | "notification-url": "https://packagist.org/downloads/", 162 | "license": [ 163 | "MIT" 164 | ], 165 | "authors": [ 166 | { 167 | "name": "Taylor Otwell", 168 | "email": "taylorotwell@gmail.com" 169 | } 170 | ], 171 | "description": "The Illuminate Support package.", 172 | "homepage": "http://laravel.com", 173 | "time": "2016-02-16 14:39:24" 174 | }, 175 | { 176 | "name": "jakoch/phantomjs-installer", 177 | "version": "2.1.1", 178 | "source": { 179 | "type": "git", 180 | "url": "https://github.com/jakoch/phantomjs-installer.git", 181 | "reference": "b8ee2aac9b95f9a9ee30a05a4df4a0984a8a8b85" 182 | }, 183 | "dist": { 184 | "type": "zip", 185 | "url": "https://api.github.com/repos/jakoch/phantomjs-installer/zipball/b8ee2aac9b95f9a9ee30a05a4df4a0984a8a8b85", 186 | "reference": "b8ee2aac9b95f9a9ee30a05a4df4a0984a8a8b85", 187 | "shasum": "" 188 | }, 189 | "require": { 190 | "ext-openssl": "*" 191 | }, 192 | "type": "custom-installer", 193 | "autoload": { 194 | "psr-0": { 195 | "PhantomInstaller\\": "src/" 196 | } 197 | }, 198 | "notification-url": "https://packagist.org/downloads/", 199 | "license": [ 200 | "MIT" 201 | ], 202 | "authors": [ 203 | { 204 | "name": "Jens-André Koch", 205 | "email": "jakoch@web.de" 206 | } 207 | ], 208 | "description": "A Composer package which installs the PhantomJS binary (Linux, Windows, Mac) into `/bin` of your project.", 209 | "keywords": [ 210 | "binaries", 211 | "headless", 212 | "phantomjs" 213 | ], 214 | "time": "2016-01-25 16:30:30" 215 | }, 216 | { 217 | "name": "jonnyw/php-phantomjs", 218 | "version": "v4.3.0", 219 | "source": { 220 | "type": "git", 221 | "url": "https://github.com/jonnnnyw/php-phantomjs.git", 222 | "reference": "59b4325be7f2a1b628cbb84f4be4fdb4adce0d6c" 223 | }, 224 | "dist": { 225 | "type": "zip", 226 | "url": "https://api.github.com/repos/jonnnnyw/php-phantomjs/zipball/59b4325be7f2a1b628cbb84f4be4fdb4adce0d6c", 227 | "reference": "59b4325be7f2a1b628cbb84f4be4fdb4adce0d6c", 228 | "shasum": "" 229 | }, 230 | "require": { 231 | "jakoch/phantomjs-installer": "~2.1", 232 | "php": ">=5.3.0", 233 | "symfony/config": "~2.3|~3.0", 234 | "symfony/dependency-injection": "~2.3|~3.0", 235 | "symfony/filesystem": "~2.3|~3.0", 236 | "symfony/yaml": "~2.3|~3.0", 237 | "twig/twig": "~1.16" 238 | }, 239 | "require-dev": { 240 | "phpunit/phpunit": "~4.0", 241 | "zendframework/zendpdf": "~2.0" 242 | }, 243 | "type": "library", 244 | "autoload": { 245 | "psr-0": { 246 | "JonnyW\\PhantomJs\\": "src" 247 | }, 248 | "classmap": [ 249 | "src/" 250 | ] 251 | }, 252 | "notification-url": "https://packagist.org/downloads/", 253 | "license": [ 254 | "MIT" 255 | ], 256 | "authors": [ 257 | { 258 | "name": "Jonny Wenmoth", 259 | "email": "contact@jonnyw.me", 260 | "homepage": "http://jonnyw.me/" 261 | } 262 | ], 263 | "description": "A PHP wrapper for loading pages through PhantomJS", 264 | "keywords": [ 265 | "Headless Browser", 266 | "phantomjs", 267 | "testing" 268 | ], 269 | "time": "2016-02-03 20:05:32" 270 | }, 271 | { 272 | "name": "symfony/config", 273 | "version": "v3.0.2", 274 | "source": { 275 | "type": "git", 276 | "url": "https://github.com/symfony/config.git", 277 | "reference": "8c83ff9a2ffbed1e606bc816db11ddc2385a16ee" 278 | }, 279 | "dist": { 280 | "type": "zip", 281 | "url": "https://api.github.com/repos/symfony/config/zipball/8c83ff9a2ffbed1e606bc816db11ddc2385a16ee", 282 | "reference": "8c83ff9a2ffbed1e606bc816db11ddc2385a16ee", 283 | "shasum": "" 284 | }, 285 | "require": { 286 | "php": ">=5.5.9", 287 | "symfony/filesystem": "~2.8|~3.0" 288 | }, 289 | "type": "library", 290 | "extra": { 291 | "branch-alias": { 292 | "dev-master": "3.0-dev" 293 | } 294 | }, 295 | "autoload": { 296 | "psr-4": { 297 | "Symfony\\Component\\Config\\": "" 298 | }, 299 | "exclude-from-classmap": [ 300 | "/Tests/" 301 | ] 302 | }, 303 | "notification-url": "https://packagist.org/downloads/", 304 | "license": [ 305 | "MIT" 306 | ], 307 | "authors": [ 308 | { 309 | "name": "Fabien Potencier", 310 | "email": "fabien@symfony.com" 311 | }, 312 | { 313 | "name": "Symfony Community", 314 | "homepage": "https://symfony.com/contributors" 315 | } 316 | ], 317 | "description": "Symfony Config Component", 318 | "homepage": "https://symfony.com", 319 | "time": "2016-01-21 09:38:31" 320 | }, 321 | { 322 | "name": "symfony/dependency-injection", 323 | "version": "v3.0.2", 324 | "source": { 325 | "type": "git", 326 | "url": "https://github.com/symfony/dependency-injection.git", 327 | "reference": "7f2ec173cc0366efa0ca1f6b1255803ed7c17028" 328 | }, 329 | "dist": { 330 | "type": "zip", 331 | "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/7f2ec173cc0366efa0ca1f6b1255803ed7c17028", 332 | "reference": "7f2ec173cc0366efa0ca1f6b1255803ed7c17028", 333 | "shasum": "" 334 | }, 335 | "require": { 336 | "php": ">=5.5.9" 337 | }, 338 | "require-dev": { 339 | "symfony/config": "~2.8|~3.0", 340 | "symfony/expression-language": "~2.8|~3.0", 341 | "symfony/yaml": "~2.8|~3.0" 342 | }, 343 | "suggest": { 344 | "symfony/config": "", 345 | "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", 346 | "symfony/yaml": "" 347 | }, 348 | "type": "library", 349 | "extra": { 350 | "branch-alias": { 351 | "dev-master": "3.0-dev" 352 | } 353 | }, 354 | "autoload": { 355 | "psr-4": { 356 | "Symfony\\Component\\DependencyInjection\\": "" 357 | }, 358 | "exclude-from-classmap": [ 359 | "/Tests/" 360 | ] 361 | }, 362 | "notification-url": "https://packagist.org/downloads/", 363 | "license": [ 364 | "MIT" 365 | ], 366 | "authors": [ 367 | { 368 | "name": "Fabien Potencier", 369 | "email": "fabien@symfony.com" 370 | }, 371 | { 372 | "name": "Symfony Community", 373 | "homepage": "https://symfony.com/contributors" 374 | } 375 | ], 376 | "description": "Symfony DependencyInjection Component", 377 | "homepage": "https://symfony.com", 378 | "time": "2016-02-02 13:48:39" 379 | }, 380 | { 381 | "name": "symfony/filesystem", 382 | "version": "v3.0.2", 383 | "source": { 384 | "type": "git", 385 | "url": "https://github.com/symfony/filesystem.git", 386 | "reference": "064ac12afd2ceb8a2c1bfb7bed8e931c6dd1997f" 387 | }, 388 | "dist": { 389 | "type": "zip", 390 | "url": "https://api.github.com/repos/symfony/filesystem/zipball/064ac12afd2ceb8a2c1bfb7bed8e931c6dd1997f", 391 | "reference": "064ac12afd2ceb8a2c1bfb7bed8e931c6dd1997f", 392 | "shasum": "" 393 | }, 394 | "require": { 395 | "php": ">=5.5.9" 396 | }, 397 | "type": "library", 398 | "extra": { 399 | "branch-alias": { 400 | "dev-master": "3.0-dev" 401 | } 402 | }, 403 | "autoload": { 404 | "psr-4": { 405 | "Symfony\\Component\\Filesystem\\": "" 406 | }, 407 | "exclude-from-classmap": [ 408 | "/Tests/" 409 | ] 410 | }, 411 | "notification-url": "https://packagist.org/downloads/", 412 | "license": [ 413 | "MIT" 414 | ], 415 | "authors": [ 416 | { 417 | "name": "Fabien Potencier", 418 | "email": "fabien@symfony.com" 419 | }, 420 | { 421 | "name": "Symfony Community", 422 | "homepage": "https://symfony.com/contributors" 423 | } 424 | ], 425 | "description": "Symfony Filesystem Component", 426 | "homepage": "https://symfony.com", 427 | "time": "2016-01-27 11:34:55" 428 | }, 429 | { 430 | "name": "symfony/yaml", 431 | "version": "v3.0.2", 432 | "source": { 433 | "type": "git", 434 | "url": "https://github.com/symfony/yaml.git", 435 | "reference": "3cf0709d7fe936e97bee9e954382e449003f1d9a" 436 | }, 437 | "dist": { 438 | "type": "zip", 439 | "url": "https://api.github.com/repos/symfony/yaml/zipball/3cf0709d7fe936e97bee9e954382e449003f1d9a", 440 | "reference": "3cf0709d7fe936e97bee9e954382e449003f1d9a", 441 | "shasum": "" 442 | }, 443 | "require": { 444 | "php": ">=5.5.9" 445 | }, 446 | "type": "library", 447 | "extra": { 448 | "branch-alias": { 449 | "dev-master": "3.0-dev" 450 | } 451 | }, 452 | "autoload": { 453 | "psr-4": { 454 | "Symfony\\Component\\Yaml\\": "" 455 | }, 456 | "exclude-from-classmap": [ 457 | "/Tests/" 458 | ] 459 | }, 460 | "notification-url": "https://packagist.org/downloads/", 461 | "license": [ 462 | "MIT" 463 | ], 464 | "authors": [ 465 | { 466 | "name": "Fabien Potencier", 467 | "email": "fabien@symfony.com" 468 | }, 469 | { 470 | "name": "Symfony Community", 471 | "homepage": "https://symfony.com/contributors" 472 | } 473 | ], 474 | "description": "Symfony Yaml Component", 475 | "homepage": "https://symfony.com", 476 | "time": "2016-02-02 13:44:19" 477 | }, 478 | { 479 | "name": "twig/twig", 480 | "version": "v1.24.0", 481 | "source": { 482 | "type": "git", 483 | "url": "https://github.com/twigphp/Twig.git", 484 | "reference": "3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8" 485 | }, 486 | "dist": { 487 | "type": "zip", 488 | "url": "https://api.github.com/repos/twigphp/Twig/zipball/3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8", 489 | "reference": "3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8", 490 | "shasum": "" 491 | }, 492 | "require": { 493 | "php": ">=5.2.7" 494 | }, 495 | "require-dev": { 496 | "symfony/debug": "~2.7", 497 | "symfony/phpunit-bridge": "~2.7" 498 | }, 499 | "type": "library", 500 | "extra": { 501 | "branch-alias": { 502 | "dev-master": "1.24-dev" 503 | } 504 | }, 505 | "autoload": { 506 | "psr-0": { 507 | "Twig_": "lib/" 508 | } 509 | }, 510 | "notification-url": "https://packagist.org/downloads/", 511 | "license": [ 512 | "BSD-3-Clause" 513 | ], 514 | "authors": [ 515 | { 516 | "name": "Fabien Potencier", 517 | "email": "fabien@symfony.com", 518 | "homepage": "http://fabien.potencier.org", 519 | "role": "Lead Developer" 520 | }, 521 | { 522 | "name": "Armin Ronacher", 523 | "email": "armin.ronacher@active-4.com", 524 | "role": "Project Founder" 525 | }, 526 | { 527 | "name": "Twig Team", 528 | "homepage": "http://twig.sensiolabs.org/contributors", 529 | "role": "Contributors" 530 | } 531 | ], 532 | "description": "Twig, the flexible, fast, and secure template language for PHP", 533 | "homepage": "http://twig.sensiolabs.org", 534 | "keywords": [ 535 | "templating" 536 | ], 537 | "time": "2016-01-25 21:22:18" 538 | } 539 | ], 540 | "packages-dev": [], 541 | "aliases": [], 542 | "minimum-stability": "dev", 543 | "stability-flags": [], 544 | "prefer-stable": true, 545 | "prefer-lowest": false, 546 | "platform": { 547 | "php": ">=5.5.9" 548 | }, 549 | "platform-dev": [] 550 | } 551 | -------------------------------------------------------------------------------- /config/poster.php: -------------------------------------------------------------------------------- 1 | storage_path('posters'), 16 | 17 | /* 18 | |-------------------------------------------------------------------------- 19 | | Default filesystem 20 | |-------------------------------------------------------------------------- 21 | | 22 | | The filesystems on which to store added files and derived images by default. 23 | | one of the filesystems you configured in app/config/filesystems.php 24 | | 25 | */ 26 | 27 | 'defaultFilesystem' => 'posters', 28 | 29 | /* 30 | |-------------------------------------------------------------------------- 31 | | Middleware token 32 | |-------------------------------------------------------------------------- 33 | | 34 | | Please specify a middleware token to protect your 35 | | view from rendering from other then PhantomJS 36 | | 37 | */ 38 | 39 | 'middleware_token' => md5('just') 40 | ]; 41 | -------------------------------------------------------------------------------- /src/Filesystem.php: -------------------------------------------------------------------------------- 1 | filesystem = $filesystems; 19 | $this->config = $config; 20 | } 21 | 22 | /** 23 | * @param File $file 24 | * @return bool 25 | */ 26 | public function put(File $file) 27 | { 28 | return $this->getDisk()->put($file->getBasename(), file_get_contents($file->getPathname()), 'public'); 29 | } 30 | 31 | /** 32 | * @param $path 33 | * @return string 34 | */ 35 | public function get($path) 36 | { 37 | return $this->getDisk()->get($path); 38 | } 39 | 40 | /** 41 | * @return \Illuminate\Contracts\Filesystem\Filesystem 42 | */ 43 | public function getDisk() 44 | { 45 | return $this->filesystem->disk($this->config->get('poster.defaultFilesystem')); 46 | } 47 | 48 | public function client() 49 | { 50 | return $this->filesystem; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/Http/Controllers/PosterController.php: -------------------------------------------------------------------------------- 1 | request = $request; 21 | } 22 | 23 | /** 24 | * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View 25 | */ 26 | public function render() 27 | { 28 | return view($this->request->get('template'), $this->request->all()); 29 | } 30 | } -------------------------------------------------------------------------------- /src/Http/Middleware/GuardRenderURI.php: -------------------------------------------------------------------------------- 1 | config = $config; 22 | } 23 | 24 | /** 25 | * Run the request filter. 26 | * 27 | * @param Request $request 28 | * @param Closure $next 29 | * @return mixed 30 | */ 31 | public function handle(Request $request, Closure $next) 32 | { 33 | $header = $request->header('X-API-POSTER-KEY'); 34 | 35 | if ($header === $this->config->get('poster.middleware_token')) { 36 | return $next($request); 37 | } 38 | 39 | return redirect('/'); 40 | } 41 | 42 | } -------------------------------------------------------------------------------- /src/Http/routes.php: -------------------------------------------------------------------------------- 1 | 'poster.render', 5 | 'as' => 'package.postergenerator', 6 | 'uses' => '\Just\PosterGenerator\Http\Controllers\PosterController@render' 7 | ]); -------------------------------------------------------------------------------- /src/PosterGenerator.php: -------------------------------------------------------------------------------- 1 | config = $config; 36 | $this->filesystem = $filesystem; 37 | $this->files = $files; 38 | } 39 | 40 | /** 41 | * @param PosterInterface $poster 42 | * @param string $extension 43 | * @return PosterResponse 44 | */ 45 | public function generateImage(PosterInterface $poster, $extension = 'jpg') 46 | { 47 | $phantom = $this->getPhantomJS(); 48 | $file = $this->getNewFile($extension); 49 | $request = $this->buildBaseRequest($phantom, $poster, $file); 50 | 51 | list($width, $height) = $poster->getViewportSize(); 52 | $request->setViewportSize($width, $height); 53 | 54 | return $this->sendPhantomRequest($phantom, $request, $file); 55 | } 56 | 57 | 58 | /** 59 | * @param PosterInterface $poster 60 | * @return PosterResponse 61 | * @throws Exception 62 | */ 63 | public function generatePDF(PosterInterface $poster) 64 | { 65 | $phantom = $this->getPhantomJS(); 66 | $file = $this->getNewFile('pdf'); 67 | $request = $this->buildBaseRequest($phantom, $poster, $file); 68 | $request->setFormat('A4'); 69 | 70 | return $this->sendPhantomRequest($phantom, $request, $file); 71 | } 72 | 73 | /** 74 | * @param PhantomJS $phantom 75 | * @param PosterInterface $poster 76 | * @param File $file 77 | * @return PdfRequest|RequestInterface 78 | * @throws Exception 79 | * @throws \JonnyW\PhantomJs\Exception\NotWritableException 80 | */ 81 | private function buildBaseRequest(PhantomJS $phantom, PosterInterface $poster, File $file) 82 | { 83 | $route = route('package.postergenerator'); 84 | 85 | switch ($file->getExtension()) { 86 | case 'jpg': 87 | case 'png': 88 | $request = $phantom->getMessageFactory()->createCaptureRequest($route); 89 | break; 90 | case 'pdf': 91 | $request = $phantom->getMessageFactory()->createPdfRequest($route); 92 | break; 93 | default: 94 | throw new Exception(sprintf('Cannot make capture of [%s]', $file->getExtension())); 95 | break; 96 | } 97 | 98 | $request->setMethod(RequestInterface::METHOD_POST); 99 | $request->setRequestData(array_merge(['template' => $poster->getTemplatePath()], $poster->getProperties())); 100 | $request->setHeaders(['X-API-POSTER-KEY' => $this->config->get('poster.middleware_token')]); 101 | 102 | $request->setOutputFile($file->getPathname()); 103 | 104 | return $request; 105 | } 106 | 107 | /** 108 | * @return PhantomJS 109 | */ 110 | private function getPhantomJS() 111 | { 112 | $path = 'bin' . DIRECTORY_SEPARATOR . 'phantomjs'; 113 | if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') $path .= '.exe'; 114 | 115 | $phantom = PhantomJS::getInstance(); 116 | $phantom->getEngine()->setPath(base_path($path)); 117 | 118 | return $phantom; 119 | } 120 | 121 | /** 122 | * @param $phantom 123 | * @param $request 124 | * @param $file 125 | * @return PosterResponse 126 | */ 127 | private function sendPhantomRequest($phantom, $request, $file) 128 | { 129 | $preResponse = $phantom->getMessageFactory()->createResponse(); 130 | $response = $phantom->send($request, $preResponse); 131 | 132 | $this->filesystem->put($file); 133 | 134 | if (file_exists($file->getPathName())) { 135 | unlink($file->getPathName()); 136 | } 137 | 138 | return new PosterResponse($response, $file); 139 | } 140 | 141 | /** 142 | * @param $extension 143 | * @return File 144 | */ 145 | private function getNewFile($extension) 146 | { 147 | $path = sprintf('%s/%s.%s', $this->config->get('poster.tempDirectory'), str_random(), $extension); 148 | return new File($path, false); 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /src/PosterInterface.php: -------------------------------------------------------------------------------- 1 | response = $response; 28 | $this->file = $file; 29 | } 30 | 31 | /** 32 | * @return Response 33 | */ 34 | public function getResponse() 35 | { 36 | return $this->response; 37 | } 38 | 39 | /** 40 | * @return File 41 | */ 42 | public function getFile() 43 | { 44 | return $this->file; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Providers/PosterGeneratorServiceProvider.php: -------------------------------------------------------------------------------- 1 | publishes([ 19 | __DIR__ . '/../../config/poster.php' => config_path('poster.php'), 20 | ]); 21 | 22 | if (! $this->app->routesAreCached()) { 23 | require __DIR__ . '/../../src/Http/routes.php'; 24 | } 25 | 26 | $router->middleware('poster.render', GuardRenderURI::class); 27 | } 28 | 29 | /** 30 | * Register any application services. 31 | * 32 | * @return void 33 | */ 34 | public function register() 35 | { 36 | $this->mergeConfigFrom( 37 | __DIR__ . '/../../config/poster.php', 'poster' 38 | ); 39 | } 40 | } 41 | --------------------------------------------------------------------------------