loading...

Your Favorite Framework is not Enough

samsonasik profile image Abdul Malik Ikhsan ・2 min read

Yes! You may be a fan of a very awesome wow Framework X. But:

Nobody's perfect. Living by supporting each other is the game called life.

Kamen Rider Skull.

You can of course tweak very hard to make your lovely framework works as your wish for your needs, but time will limit it.

Whenever there is another tools that just right for that, you should just use them - combine them - profit.

A Use Case

I got a project using PHP, and I use Zend Framework. Everything seems perfect in the beginning, all I needs were in there, until a reporting feature coming. I need a html to pdf converter. After I tried many PHP libs, I found a one that suit my needs, which named Snappy , which can be easily required via composer command:

$ composer require knplabs/knp-snappy

This lib require non-php executable command line tools, named wkhtmltopdf

If I remember correctly, my client want to code also in his windows, the server is using linux, and for my dev tools, I am using OS X. Virtual Machine is not a solution at that time as I have limited resource, so, I downloaded 3 versions (windows, linux, and mac) of the executable files in my application.

.
├── bin
│   ├── linux
│   │   └── wkhtmltopdf
│   ├── mac
│   │   └── wkhtmltopdf
│   └── windows
│       ├── bin
│       │   ├── wkhtmltoimage.exe
│       │   ├── wkhtmltopdf.exe
│       │   └── wkhtmltox.dll
│       ├── include
│       │   └── wkhtmltox
│       └── lib
│           └── wkhtmltox.lib

I created a simple code to detect os which returns wkhtmltopdf executable file like the following :

<?php
private function getWkhtmlToPdfLocation()
{
    $os = PHP_OS;

    if ($os === 'Darwin' || $os === 'Linux') {
        $os = ($os === 'Darwin') ? 'mac' : strtolower($os);
        return realpath(getcwd() . '/bin/' . $os . '/wkhtmltopdf');
    }

    return realpath(getcwd() . '/bin/windows/bin/wkhtmltopdf.exe');
}

I need to generate a pdf from html report, and download it, then I do following action:

<?php

use Knp\Snappy\Pdf;
use Zend\View\Model\ViewModel;

// ... demo: not actual code
public function generatereportAction()
{
    $filename = '/path/to/report.pdf';    

    $snappy = new Pdf($this->getWkhtmlToPdfLocation());
    $snappy->generateFromHtml($this->getOutput(), $filename);

    return $this->sendResponse($filename);
}

Here I created separate methods to buffer html output and send response to ease you to see the logic for above action:

<?php
// ... demo: not actual code
private function getOutput()
{
    $viewModel = new ViewModel();
    $viewModel->setTemplate('/application/report')->setTerminal(true);

    // renderer is a Zend\View\Renderer\PhpRenderer instance
    $output = $this->renderer->render($viewModel);   

    return $output;
}

private function sendResponse($filename)
{
    $response = $this->getResponse();

    $response->getHeaders()->addHeaderLine('Content-Type', 'application/pdf');
    $response->getHeaders()->addHeaderLine('Content-Disposition', 'attachment; filename="'.basename($filename).'"');
    $response->getHeaders()->addHeaderLine('Content-Length', filesize($filename));

    $response->setContent(file_get_contents($filename));

    //remove file after not needed
    @unlink($filename);

    return $response;
}

Well, You can of course wrap them inside service, models, use bundled module for its service to be usable in many applications, you name it.

Conclusion

Be open minded.

Discussion

pic
Editor guide