2015-04-01 2 views
4

Я создал контроллер Bundle и REST внутри. "Индекс" метод возвращения массива в JSON-формате, это нормально:Symfony2 FOSRESTBundle REST API для возврата PDF

MyBundle/контроллер/Api/Отдых/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/Ресурсы/конфигурации/апи /routing_rest.yml

my_api_rest_bacon: 
    type: rest 
    resource: "MyBundle:Api/Rest/Bacon" 
    name_prefix: api_rest_bacon_ 
    prefix: /my/bacon 

Таким образом, на данный момент результаты JSON получить вернулся отлично:

mysite.com/app_dev.php/api/my/bacon/bacons.json

возвращает свой массив.

Но теперь мне нужно, чтобы мой контроллер сгенерировал PDF с данными. Поэтому я хочу, чтобы вернуть PDF документ, когда я называю:

mysite.com/app_dev.php/api/my/bacon/bacons.pdf

Я нашел несколько половин руководства: RSS view handler, RSS config.ynal, CSV issue with answers. И пытались сделать что-то подобное:

я добавил эти строки в

Symfony/приложение/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()); 
    } 
} 

Так что теперь, когда я звоню

mysite.com/app_dev.php/api/my/bacon/bacons.pdf

Я вижу ошибку An Exception was thrown while handling: Format html not supported, handler must be implemented и моя функция my_dump сохраняет в текстовый файл информация о формате файла: html, а не pdf.

Также pdf createResponse не работал. Зачем?

ответ

7

Таким образом, я нашел решение (я опишу, как включить 2 выходных форматов: PDF и XLS):

1) В этом разделе в config.yml не нужен:

framework: 
    [...some old stuff here...] 
    request: 
     formats: 
      pdf: 'application/pdf' 

2) fos_rest.format_listener раздел в config.yml должен выглядеть следующим образом:

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) нужно добавить service раздел вв config.yml

fos_rest: 
[...] 
    service: 
     view_handler: my.view_handler 

4) services корневой раздел в config.yml должен выглядеть

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'] ] ] 

И это он. Теперь он отлично работает

+0

Не могли бы вы добавить исходный код для XlsViewHandler или PdfViewHandler? –

+2

@przemo_li http://symfony.com/doc/current/bundles/FOSRestBundle/2-the-view-layer.html#custom-handler может предоставить вам полезную информацию – StrikeForceZero

1

Если файлы будут иметь различное содержимое данных, тогда контроллер может также генерировать файл самостоятельно, возвращая результаты в BinaryFileResponse.

  • Нет необходимости изменять любой конфигурации
  • _format может быть использован, чтобы выбрать формат желаемого файла
  • Весь код находиться внутри контроллера (и некоторых услуг, связанных с определенным форматом GEN), так что добавление нового материала или изменения существующих требуют изменений в небольшом количестве файлов.
Смежные вопросы