Today we’re going to play with QR codes and how to use them within a Silex application using one Service Provider. First we need a QR code generator. If we find in Packagist we can see various libraries. We are going to use the library: endroid/qrcode.
We are not going to modify endroid/qrcode, because of that we will create a wrapper. This wrapper will receive in the constructor one instance of endroid/qrcode. It’s responsability will be to take one QrCode object and generate a Symfony\Component\HttpFoundation\Response with our QR code and the properly headers. Here you can see the unit tests of our QrWrapper:
use Symfony\Component\HttpFoundation\Response;
use G\QrWrapper;
class QrWrapperTest extends PHPUnit_Framework_TestCase
{
public function testObjectInit()
{
$qrCode = $this->getMockBuilder('Endroid\QrCode\QrCode')
->disableOriginalConstructor()
->getMock();
$wrapper = new QrWrapper($qrCode);
$this->assertInstanceOf('G\QrWrapper', $wrapper);
}
public function testGetResponseWithDefaultParameters()
{
$qrCode = $this->getMockBuilder('Endroid\QrCode\QrCode')
->disableOriginalConstructor()
->getMock();
$qrCode->expects($this->any())->method('get')->will($this->returnValue("hello"));
$wrapper = new QrWrapper($qrCode);
$response = $wrapper->getResponse();
$this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $response);
$this->assertEquals("hello", $response->getContent());
$this->assertEquals("image/png", $response->headers->get('Content-Type'));
}
public function testGetResponseForJpg()
{
$qrCode = $this->getMockBuilder('Endroid\QrCode\QrCode')
->disableOriginalConstructor()
->getMock();
$qrCode->expects($this->any())->method('get')->will($this->returnValue("hello"));
$wrapper = new QrWrapper($qrCode);
$wrapper->setImageType('jpg');
$response = $wrapper->getResponse();
$this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $response);
$this->assertEquals("hello", $response->getContent());
$this->assertEquals("image/jpeg", $response->headers->get('Content-Type'));
}
public function testGetResponseForJpeg()
{
$qrCode = $this->getMockBuilder('Endroid\QrCode\QrCode')
->disableOriginalConstructor()
->getMock();
$qrCode->expects($this->any())->method('get')->will($this->returnValue("hello"));
$wrapper = new QrWrapper($qrCode);
$wrapper->setImageType('jpeg');
$response = $wrapper->getResponse();
$this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $response);
$this->assertEquals("hello", $response->getContent());
$this->assertEquals("image/jpeg", $response->headers->get('Content-Type'));
}
public function testReusingResponse()
{
$qrCode = $this->getMockBuilder('Endroid\QrCode\QrCode')
->disableOriginalConstructor()
->getMock();
$qrCode->expects($this->any())->method('get')->will($this->returnValue("hello"));
$wrapper = new QrWrapper($qrCode);
$response = new Response('foo');
$response->headers->set('xxx', 'gonzalo');
$response = $wrapper->getResponse($response);
$this->assertEquals("hello", $response->getContent());
$this->assertEquals("image/png", $response->headers->get('Content-Type'));
$this->assertEquals("gonzalo", $response->headers->get('xxx'));
}
}
Now we will create the ServiceProvider. We only need to implement ServiceProviderInterface
use Silex\Application;
use Silex\ServiceProviderInterface;
use Endroid\QrCode\QrCode;
class QrServiceProvider implements ServiceProviderInterface
{
public function register(Application $app)
{
$app['qrCode'] = $app->protect(function ($text, $size = null) use ($app) {
$default = $app['qr.defaults'];
$qr = new QrWrapper(new QrCode());
$qr->setText($text);
$qr->setPadding($default['padding']);
$qr->setSize(is_null($size) ? $default['size'] : $size);
$qr->setImageType($default['imageType']);
return $qr;
});
}
public function boot(Application $app)
{
}
}
And that’s all. Now we can use our service provider within one Silex Application:
use Silex\Application;
use G\QrServiceProvider;
$app = new Application();
$app->register(new QrServiceProvider(), [
'qr.defaults' => [
'padding' => 5, // default: 0
'size' => 200,
'imageType' => 'png', // png, gif, jpeg, wbmp (default: png)
]
]);
$app->get("/qr/base64/{text}", function($text) use ($app) {
return $app['qrCode'](base64_decode($text))->getResponse();
});
$app->get("/qr/{text}", function($text) use ($app) {
return $app['qrCode']($text)->getResponse();
});
$app->run();
You can fetch the full code in github and also use it with composer