dff3773d38a7192f51e5eb520b44a71c19c4b443
[yaffs-website] / vendor / symfony / http-kernel / Fragment / FragmentHandler.php
1 <?php
2
3 /*
4  * This file is part of the Symfony package.
5  *
6  * (c) Fabien Potencier <fabien@symfony.com>
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11
12 namespace Symfony\Component\HttpKernel\Fragment;
13
14 use Symfony\Component\HttpFoundation\Request;
15 use Symfony\Component\HttpFoundation\Response;
16 use Symfony\Component\HttpFoundation\StreamedResponse;
17 use Symfony\Component\HttpFoundation\RequestStack;
18 use Symfony\Component\HttpKernel\Controller\ControllerReference;
19
20 /**
21  * Renders a URI that represents a resource fragment.
22  *
23  * This class handles the rendering of resource fragments that are included into
24  * a main resource. The handling of the rendering is managed by specialized renderers.
25  *
26  * This listener works in 2 modes:
27  *
28  *  * 2.3 compatibility mode where you must call setRequest whenever the Request changes.
29  *  * 2.4+ mode where you must pass a RequestStack instance in the constructor.
30  *
31  * @author Fabien Potencier <fabien@symfony.com>
32  *
33  * @see FragmentRendererInterface
34  */
35 class FragmentHandler
36 {
37     private $debug;
38     private $renderers = array();
39     private $request;
40     private $requestStack;
41
42     /**
43      * Constructor.
44      *
45      * RequestStack will become required in 3.0.
46      *
47      * @param RequestStack                $requestStack The Request stack that controls the lifecycle of requests
48      * @param FragmentRendererInterface[] $renderers    An array of FragmentRendererInterface instances
49      * @param bool                        $debug        Whether the debug mode is enabled or not
50      */
51     public function __construct($requestStack = null, $renderers = array(), $debug = false)
52     {
53         if (is_array($requestStack)) {
54             $tmp = $debug;
55             $debug = func_num_args() < 2 ? false : $renderers;
56             $renderers = $requestStack;
57             $requestStack = func_num_args() < 3 ? null : $tmp;
58
59             @trigger_error('The '.__METHOD__.' method now requires a RequestStack to be given as first argument as '.__CLASS__.'::setRequest method will not be supported anymore in 3.0.', E_USER_DEPRECATED);
60         } elseif (!$requestStack instanceof RequestStack) {
61             @trigger_error('The '.__METHOD__.' method now requires a RequestStack instance as '.__CLASS__.'::setRequest method will not be supported anymore in 3.0.', E_USER_DEPRECATED);
62         }
63
64         if (null !== $requestStack && !$requestStack instanceof RequestStack) {
65             throw new \InvalidArgumentException('RequestStack instance expected.');
66         }
67         if (!is_array($renderers)) {
68             throw new \InvalidArgumentException('Renderers must be an array.');
69         }
70
71         $this->requestStack = $requestStack;
72         foreach ($renderers as $renderer) {
73             $this->addRenderer($renderer);
74         }
75         $this->debug = $debug;
76     }
77
78     /**
79      * Adds a renderer.
80      *
81      * @param FragmentRendererInterface $renderer A FragmentRendererInterface instance
82      */
83     public function addRenderer(FragmentRendererInterface $renderer)
84     {
85         $this->renderers[$renderer->getName()] = $renderer;
86     }
87
88     /**
89      * Sets the current Request.
90      *
91      * This method was used to synchronize the Request, but as the HttpKernel
92      * is doing that automatically now, you should never call it directly.
93      * It is kept public for BC with the 2.3 version.
94      *
95      * @param Request|null $request A Request instance
96      *
97      * @deprecated since version 2.4, to be removed in 3.0.
98      */
99     public function setRequest(Request $request = null)
100     {
101         @trigger_error('The '.__METHOD__.' method is deprecated since version 2.4 and will be removed in 3.0.', E_USER_DEPRECATED);
102
103         $this->request = $request;
104     }
105
106     /**
107      * Renders a URI and returns the Response content.
108      *
109      * Available options:
110      *
111      *  * ignore_errors: true to return an empty string in case of an error
112      *
113      * @param string|ControllerReference $uri      A URI as a string or a ControllerReference instance
114      * @param string                     $renderer The renderer name
115      * @param array                      $options  An array of options
116      *
117      * @return string|null The Response content or null when the Response is streamed
118      *
119      * @throws \InvalidArgumentException when the renderer does not exist
120      * @throws \LogicException           when no master request is being handled
121      */
122     public function render($uri, $renderer = 'inline', array $options = array())
123     {
124         if (!isset($options['ignore_errors'])) {
125             $options['ignore_errors'] = !$this->debug;
126         }
127
128         if (!isset($this->renderers[$renderer])) {
129             throw new \InvalidArgumentException(sprintf('The "%s" renderer does not exist.', $renderer));
130         }
131
132         if (!$request = $this->getRequest()) {
133             throw new \LogicException('Rendering a fragment can only be done when handling a Request.');
134         }
135
136         return $this->deliver($this->renderers[$renderer]->render($uri, $request, $options));
137     }
138
139     /**
140      * Delivers the Response as a string.
141      *
142      * When the Response is a StreamedResponse, the content is streamed immediately
143      * instead of being returned.
144      *
145      * @param Response $response A Response instance
146      *
147      * @return string|null The Response content or null when the Response is streamed
148      *
149      * @throws \RuntimeException when the Response is not successful
150      */
151     protected function deliver(Response $response)
152     {
153         if (!$response->isSuccessful()) {
154             throw new \RuntimeException(sprintf('Error when rendering "%s" (Status code is %s).', $this->getRequest()->getUri(), $response->getStatusCode()));
155         }
156
157         if (!$response instanceof StreamedResponse) {
158             return $response->getContent();
159         }
160
161         $response->sendContent();
162     }
163
164     private function getRequest()
165     {
166         return $this->requestStack ? $this->requestStack->getCurrentRequest() : $this->request;
167     }
168 }