diff --git a/src/Compiler.php b/src/Compiler.php index 9b2ee96..b92f6e4 100644 --- a/src/Compiler.php +++ b/src/Compiler.php @@ -2,10 +2,48 @@ namespace Zoomyboy\Tex; -class Compiler +use Illuminate\Contracts\Support\Responsable; +use Illuminate\Http\File; +use Illuminate\Support\Str; + +class Compiler implements Responsable { - public function compile(Document $document): string + public File $file; + + public function compile(Document $document): self { - return '/tmp/file.pdf'; + $filename = $document->filename(); + $dir = Str::random(32); + + $contents = view()->make($document->view(), get_object_vars($document))->render(); + + mkdir('/tmp/'.$dir); + file_put_contents('/tmp/'.$dir.'/'.$document->filename().'.tex', $contents); + + if ($document->template()) { + $templatePath = resource_path("views/tex/templates/{$document->template()}"); + exec('cp '.$templatePath.'/* /tmp/'.$dir); + } + + $command = 'cd /tmp/'.$dir; + $command .= ' && '.$document->getEngine().' --halt-on-error '.$document->filename().'.tex'; + $command .= ' && '.$document->getEngine().' --halt-on-error '.$document->filename().'.tex'; + exec($command, $output, $returnVar); + + if (file_exists('/tmp/'.$dir.'/'.$document->filename().'.pdf')) { + $this->file = new File('/tmp/'.$dir.'/'.$document->filename().'.pdf'); + } else { + throw new Exception('Compilation failed'); + } + + return $this; + } + + public function toResponse($request) + { + return response()->file($this->file->getRealPath(), [ + 'Content-Type' => 'application/pdf', + 'Content-Disposition' => "inline; filename=\"{$this->file->getFilename()}\"", + ]); } } diff --git a/src/CompilerFake.php b/src/CompilerFake.php new file mode 100644 index 0000000..7054c27 --- /dev/null +++ b/src/CompilerFake.php @@ -0,0 +1,62 @@ + + */ + private array $compiledDocuments = []; + + /** + * @param class-string $documentClass + * @param callable(Document): bool $check + */ + public function assertCompiled(string $documentClass, callable $check): void + { + $compilations = $this->getCompilations($documentClass); + Assert::assertFalse( + $compilations->isEmpty(), + 'The TeX Document "'.$documentClass.'" has not been compiled at all.' + ); + + Assert::assertFalse( + $compilations->isEmpty(), + 'The TeX Document "'.$documentClass.'" has not been compiled.' + ); + + $validDocuments = $compilations->filter(fn ($compilation) => $check($compilation)); + + Assert::assertNotEmpty($validDocuments, 'Failed that TeX Document "'.$documentClass.'" has been compiled with given check.'); + } + + /** + * @param class-string $documentClass + * + * @return Collection + */ + protected function getCompilations(string $documentClass): Collection + { + return collect($this->compiledDocuments)->filter(fn ($rendered) => get_class($rendered) === $documentClass); + } + + public function compile(Document $document): self + { + $path = '/tmp/'.$document->filename().'.pdf'; + $file = UploadedFile::fake()->create($document->filename().'.pdf', 100, 'application/pdf'); + + file_put_contents($path, $file->get()); + + $this->file = new File($path, true); + + $this->compiledDocuments[] = $document; + + return $this; + } +} diff --git a/src/CompilerSpy.php b/src/CompilerSpy.php index 7c29137..a2ce69e 100644 --- a/src/CompilerSpy.php +++ b/src/CompilerSpy.php @@ -49,12 +49,12 @@ class CompilerSpy return collect($this->compiledDocuments)->filter(fn ($rendered) => get_class($rendered) === $documentClass); } - public function compile(Document $document): string + public function compile(Document $document): Compiler { - $filename = static::$actualCompiler->compile($document); + $compiler = static::$actualCompiler->compile($document); $this->compiledDocuments[] = $document; - return $filename; + return $compiler; } } diff --git a/src/Document.php b/src/Document.php index 29e7228..c2f4119 100644 --- a/src/Document.php +++ b/src/Document.php @@ -6,6 +6,14 @@ use PHPUnit\Framework\Assert; abstract class Document { + abstract public function filename(): string; + + abstract public function view(): string; + + abstract public function template(): ?string; + + abstract public function getEngine(): string; + public function assertHasContent(string $content): void { Assert::assertStringContainsString( diff --git a/src/Tex.php b/src/Tex.php index fabbecc..825f64d 100644 --- a/src/Tex.php +++ b/src/Tex.php @@ -5,7 +5,7 @@ namespace Zoomyboy\Tex; use Illuminate\Support\Facades\Facade; /** - * @method static void assertCompiled(class-string $documentClass, callable(Document): bool $check) + * @method static void assertCompiled(class-string $documentClass, Closure(Document): bool $check) * @method static void compile(Document $document) */ class Tex extends Facade