1<?php 2 3/* 4 * This file is part of the Assetic package, an OpenSky project. 5 * 6 * (c) 2010-2014 OpenSky Project Inc 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12namespace Assetic\Filter; 13 14use Assetic\Asset\AssetInterface; 15use Assetic\Exception\FilterException; 16use Assetic\Util\FilesystemUtils; 17 18/** 19 * Compiles Handlebars templates into Javascript. 20 * 21 * @link http://handlebarsjs.com/ 22 * @author Keyvan Akbary <keyvan@funddy.com> 23 */ 24class HandlebarsFilter extends BaseNodeFilter 25{ 26 private $handlebarsBin; 27 private $nodeBin; 28 29 private $minimize = false; 30 private $simple = false; 31 32 public function __construct($handlebarsBin = '/usr/bin/handlebars', $nodeBin = null) 33 { 34 $this->handlebarsBin = $handlebarsBin; 35 $this->nodeBin = $nodeBin; 36 } 37 38 public function setMinimize($minimize) 39 { 40 $this->minimize = $minimize; 41 } 42 43 public function setSimple($simple) 44 { 45 $this->simple = $simple; 46 } 47 48 public function filterLoad(AssetInterface $asset) 49 { 50 $pb = $this->createProcessBuilder($this->nodeBin 51 ? array($this->nodeBin, $this->handlebarsBin) 52 : array($this->handlebarsBin)); 53 54 if ($sourcePath = $asset->getSourcePath()) { 55 $templateName = basename($sourcePath); 56 } else { 57 throw new \LogicException('The handlebars filter requires that assets have a source path set'); 58 } 59 60 $inputDirPath = FilesystemUtils::createThrowAwayDirectory('handlebars_in'); 61 $inputPath = $inputDirPath.DIRECTORY_SEPARATOR.$templateName; 62 $outputPath = FilesystemUtils::createTemporaryFile('handlebars_out'); 63 64 file_put_contents($inputPath, $asset->getContent()); 65 66 $pb->add($inputPath)->add('-f')->add($outputPath); 67 68 if ($this->minimize) { 69 $pb->add('--min'); 70 } 71 72 if ($this->simple) { 73 $pb->add('--simple'); 74 } 75 76 $process = $pb->getProcess(); 77 $returnCode = $process->run(); 78 79 unlink($inputPath); 80 rmdir($inputDirPath); 81 82 if (127 === $returnCode) { 83 throw new \RuntimeException('Path to node executable could not be resolved.'); 84 } 85 86 if (0 !== $returnCode) { 87 if (file_exists($outputPath)) { 88 unlink($outputPath); 89 } 90 throw FilterException::fromProcess($process)->setInput($asset->getContent()); 91 } 92 93 if (!file_exists($outputPath)) { 94 throw new \RuntimeException('Error creating output file.'); 95 } 96 97 $compiledJs = file_get_contents($outputPath); 98 unlink($outputPath); 99 100 $asset->setContent($compiledJs); 101 } 102 103 public function filterDump(AssetInterface $asset) 104 { 105 } 106} 107