I've made a Bundle and a REST controller inside. The "index" method return array in JSON-format, it's ok:
MyBundle/Controller/Api/Rest/BaconController.php
class BaconController extends Controller implements ClassResourceInterface
{
/**
* @var Request $request
* @return array
* @Rest\View
*/
public function cgetAction(Request $request)
{
$mediaType = $request->attributes->get('media_type');
$format = $request->getFormat($mediaType);
my_dump($format);
return array(
array("id" => 1, "title" => "hello",),
array("id" => 2, "title" => "there",),
);
}
}
MyBundle/Resources/config/api/routing_rest.yml
my_api_rest_bacon:
type: rest
resource: "MyBundle:Api/Rest/Bacon"
name_prefix: api_rest_bacon_
prefix: /my/bacon
So, at this point JSON results get returned perfectly:
mysite.com/app_dev.php/api/my/bacon/bacons.json
returns my array.
But now I need to get my controller generate a PDF with the data. So I want it to return PDF document when I call:
mysite.com/app_dev.php/api/my/bacon/bacons.pdf
I've found some half-manuals: RSS view handler, RSS config.ynal, CSV issue with answers. And tried to make something similar:
I've added these lines to
Symfony/app/config/config.yml
framework:
[...some old stuff here...]
request:
formats:
pdf: 'application/pdf'
fos_rest:
body_converter:
enabled: true
format_listener:
rules:
# Prototype array
-
# URL path info
path: ~
# URL host name
host: ~
prefer_extension: true
fallback_format: html
priorities: [html,json]
-
path: ~
host: ~
prefer_extension: true
fallback_format: pdf
priorities: [pdf]
view:
# @View or @Template
view_response_listener: force #true
formats:
json: true
pdf: true
xls: true
html: false
templating_formats:
pdf: false
xls: false
mime_types: {'pdf': ['application/pdf']}
routing_loader:
default_format: html
param_fetcher_listener: true
body_listener: true
allowed_methods_listener: true
services:
my.view_handler.pdf:
class: Lobster\MyBundle\View\PdfViewHandler
my.view_handler:
parent: fos_rest.view_handler.default
calls:
- ['registerHandler', [ 'pdf', [@my.view_handler.pdf, 'createResponse'] ] ]
MyBundle/View/PdfViewHandler.php
namespace Lobster\MyBundle\View;
use FOS\RestBundle\View\View;
use FOS\RestBundle\View\ViewHandler;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class PdfViewHandler
{
public function createResponse(ViewHandler $handler, View $view, Request $request, $format)
{
my_dump('pdf createResponse started');
$pdf = "some pdf";
return new Response($pdf, 200, $view->getHeaders());
}
}
So now when I call
mysite.com/app_dev.php/api/my/bacon/bacons.pdf
I see an error An Exception was thrown while handling: Format html not supported, handler must be implemented
and my function my_dump
saves to a text file info about file format: it is html
, not pdf
.
Also pdf createResponse
didn't work. Why?
So I've found the solution (I will describe how to enable 2 output formats: PDF and XLS):
1) This section in config.yml
is not needed:
framework:
[...some old stuff here...]
request:
formats:
pdf: 'application/pdf'
2) fos_rest.format_listener
section in config.yml
should look like this:
format_listener:
rules:
-
path: '^/api/my/bacon.*\.xls$'
host: ~
prefer_extension: false
fallback_format: json
priorities: [xls, json]
-
path: '^/api/my/bacon.*\.pdf$'
host: ~
prefer_extension: false
fallback_format: json
priorities: [pdf, json]
-
path: ~
host: ~
prefer_extension: true
fallback_format: html
priorities: [html,json]
3) need to add service
section into fos_rest
in config.yml
fos_rest:
[...]
service:
view_handler: my.view_handler
4) services
root section in config.yml
should look like
services:
my.view_handler.xls:
class: Lobster\MyBundle\View\XlsViewHandler
my.view_handler.pdf:
class: Lobster\MyBundle\View\PdfViewHandler
my.view_handler:
parent: fos_rest.view_handler.default
calls:
- ['registerHandler', ['xls', [@my.view_handler.xls, 'createResponse'] ] ]
- ['registerHandler', ['pdf', [@my.view_handler.pdf, 'createResponse'] ] ]
And this is it. Now it works perfect
If files will have different data content, then Controller could as well generate file on their own, returning results in BinaryFileResponse.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With