FragmentHandler.php 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\HttpKernel\Fragment;
  11. use Symfony\Component\HttpFoundation\Request;
  12. use Symfony\Component\HttpFoundation\Response;
  13. use Symfony\Component\HttpFoundation\StreamedResponse;
  14. use Symfony\Component\HttpKernel\Controller\ControllerReference;
  15. /**
  16. * Renders a URI that represents a resource fragment.
  17. *
  18. * This class handles the rendering of resource fragments that are included into
  19. * a main resource. The handling of the rendering is managed by specialized renderers.
  20. *
  21. * @author Fabien Potencier <fabien@symfony.com>
  22. *
  23. * @see FragmentRendererInterface
  24. */
  25. class FragmentHandler
  26. {
  27. private $debug;
  28. private $renderers;
  29. private $request;
  30. /**
  31. * Constructor.
  32. *
  33. * @param FragmentRendererInterface[] $renderers An array of FragmentRendererInterface instances
  34. * @param Boolean $debug Whether the debug mode is enabled or not
  35. */
  36. public function __construct(array $renderers = array(), $debug = false)
  37. {
  38. $this->renderers = array();
  39. foreach ($renderers as $renderer) {
  40. $this->addRenderer($renderer);
  41. }
  42. $this->debug = $debug;
  43. }
  44. /**
  45. * Adds a renderer.
  46. *
  47. * @param FragmentRendererInterface $renderer A FragmentRendererInterface instance
  48. */
  49. public function addRenderer(FragmentRendererInterface $renderer)
  50. {
  51. $this->renderers[$renderer->getName()] = $renderer;
  52. }
  53. /**
  54. * Sets the current Request.
  55. *
  56. * @param Request $request The current Request
  57. */
  58. public function setRequest(Request $request = null)
  59. {
  60. $this->request = $request;
  61. }
  62. /**
  63. * Renders a URI and returns the Response content.
  64. *
  65. * Available options:
  66. *
  67. * * ignore_errors: true to return an empty string in case of an error
  68. *
  69. * @param string|ControllerReference $uri A URI as a string or a ControllerReference instance
  70. * @param string $renderer The renderer name
  71. * @param array $options An array of options
  72. *
  73. * @return string|null The Response content or null when the Response is streamed
  74. *
  75. * @throws \InvalidArgumentException when the renderer does not exist
  76. * @throws \RuntimeException when the Response is not successful
  77. */
  78. public function render($uri, $renderer = 'inline', array $options = array())
  79. {
  80. if (!isset($options['ignore_errors'])) {
  81. $options['ignore_errors'] = !$this->debug;
  82. }
  83. if (!isset($this->renderers[$renderer])) {
  84. throw new \InvalidArgumentException(sprintf('The "%s" renderer does not exist.', $renderer));
  85. }
  86. if (null === $this->request) {
  87. throw new \LogicException('Rendering a fragment can only be done when handling a master Request.');
  88. }
  89. return $this->deliver($this->renderers[$renderer]->render($uri, $this->request, $options));
  90. }
  91. /**
  92. * Delivers the Response as a string.
  93. *
  94. * When the Response is a StreamedResponse, the content is streamed immediately
  95. * instead of being returned.
  96. *
  97. * @param Response $response A Response instance
  98. *
  99. * @return string|null The Response content or null when the Response is streamed
  100. *
  101. * @throws \RuntimeException when the Response is not successful
  102. */
  103. protected function deliver(Response $response)
  104. {
  105. if (!$response->isSuccessful()) {
  106. throw new \RuntimeException(sprintf('Error when rendering "%s" (Status code is %s).', $this->request->getUri(), $response->getStatusCode()));
  107. }
  108. if (!$response instanceof StreamedResponse) {
  109. return $response->getContent();
  110. }
  111. $response->sendContent();
  112. }
  113. }