Example #1
0
 public function testGetCurrentRequest()
 {
     $requestStack = new RequestStack();
     $this->assertNull($requestStack->getCurrentRequest());
     $request = Request::create('/foo');
     $requestStack->push($request);
     $this->assertSame($request, $requestStack->getCurrentRequest());
     $this->assertSame($request, $requestStack->pop());
     $this->assertNull($requestStack->getCurrentRequest());
     $this->assertNull($requestStack->pop());
 }
Example #2
0
 /**
  * @covers ::__construct
  * @covers ::getRouteObject
  * @covers ::getCurrentRouteMatch
  * @covers ::getRouteMatch
  */
 public function testGetCurrentRouteObject()
 {
     $request_stack = new RequestStack();
     $request = new Request();
     $request_stack->push($request);
     $current_route_match = new CurrentRouteMatch($request_stack);
     // Before routing.
     $this->assertNull($current_route_match->getRouteObject());
     // After routing.
     $route = new Route('/test-route/{foo}');
     $request->attributes->set(RouteObjectInterface::ROUTE_NAME, 'test_route');
     $request->attributes->set(RouteObjectInterface::ROUTE_OBJECT, $route);
     $request->attributes->set('foo', '1');
     $this->assertSame('1', $current_route_match->getParameter('foo'));
     // Immutable for the same request once a route has been matched.
     $request->attributes->set('foo', '2');
     $this->assertSame('1', $current_route_match->getParameter('foo'));
     // Subrequest.
     $subrequest = new Request();
     $subrequest->attributes->set(RouteObjectInterface::ROUTE_NAME, 'test_subrequest_route');
     $subrequest->attributes->set(RouteObjectInterface::ROUTE_OBJECT, new Route('/test-subrequest-route/{foo}'));
     $subrequest->attributes->set('foo', '2');
     $request_stack->push($subrequest);
     $this->assertSame('2', $current_route_match->getParameter('foo'));
     // Restored original request.
     $request_stack->pop();
     $this->assertSame('1', $current_route_match->getParameter('foo'));
 }
Example #3
0
 /**
  * @param $params
  * @return mixed|string
  * @throws SmartyPluginException
  */
 public function processRender($params)
 {
     if (null === $params["action"]) {
         throw new SmartyPluginException("You must declare the 'action' parameter in the 'render' smarty function");
     }
     $request = $this->prepareRequest($params);
     $this->requestStack->push($request);
     $controller = $this->controllerResolver->getController($request);
     $controllerParameters = $this->controllerResolver->getArguments($request, $controller);
     $response = call_user_func_array($controller, $controllerParameters);
     $this->requestStack->pop();
     if ($response instanceof Response) {
         return $response->getContent();
     }
     return $response;
 }
Example #4
0
 /**
  * Handles the response event.
  *
  * @param  Response $response
  * @return Response
  */
 protected function handleResponse(Response $response)
 {
     $event = new KernelEvent('response', $this);
     $this->events->trigger($event, [$this->getRequest(), $response]);
     $this->stack->pop();
     return $response;
 }
Example #5
0
 protected function finishRequest(Request $request, $type)
 {
     if ($this->eventDispatcher !== null) {
         $event = new FinishRequestEvent($this, $request, $type);
         $this->eventDispatcher->dispatch(KernelEvents::FINISH_REQUEST, $event);
     }
     $this->requests->pop();
 }
 /**
  * Filters the given embedded response, using the cumulative AJAX page state.
  *
  * @param \Symfony\Component\HttpFoundation\Request $fake_request
  *   A fake subrequest that contains the cumulative AJAX page state of the
  *   HTML document and all preceding Embedded HTML or AJAX responses.
  * @param \Symfony\Component\HttpFoundation\Response|\Drupal\Core\Render\HtmlResponse|\Drupal\Core\Ajax\AjaxResponse $embedded_response
  *   Either a HTML response or an AJAX response that will be embedded in the
  *   overall HTML response.
  *
  * @return \Symfony\Component\HttpFoundation\Response
  *   The filtered response, which will load only the assets that $fake_request
  *   did not indicate to already have been loaded, plus the updated cumulative
  *   AJAX page state.
  */
 protected function filterEmbeddedResponse(Request $fake_request, Response $embedded_response)
 {
     assert('$embedded_response instanceof \\Drupal\\Core\\Render\\HtmlResponse || $embedded_response instanceof \\Drupal\\Core\\Ajax\\AjaxResponse');
     $this->requestStack->push($fake_request);
     $event = new FilterResponseEvent($this->httpKernel, $fake_request, HttpKernelInterface::SUB_REQUEST, $embedded_response);
     $this->eventDispatcher->dispatch(KernelEvents::RESPONSE, $event);
     $filtered_response = $event->getResponse();
     $this->requestStack->pop();
     return $filtered_response;
 }
Example #7
0
 /**
  * Tests the request path condition.
  */
 public function testConditions()
 {
     // Get the request path condition and test and configure it to check against
     // different patterns and requests.
     $pages = "/my/pass/page\r\n/my/pass/page2\r\n/foo";
     $request = Request::create('/my/pass/page2');
     $this->requestStack->push($request);
     /* @var \Drupal\system\Plugin\Condition\RequestPath $condition */
     $condition = $this->pluginManager->createInstance('request_path');
     $condition->setConfig('pages', $pages);
     $this->aliasManager->addAlias('/my/pass/page2', '/my/pass/page2');
     $this->assertTrue($condition->execute(), 'The request path matches a standard path');
     $this->assertEqual($condition->summary(), 'Return true on the following pages: /my/pass/page, /my/pass/page2, /foo', 'The condition summary matches for a standard path');
     // Test an aliased path.
     $this->currentPath->setPath('/my/aliased/page', $request);
     $this->requestStack->pop();
     $this->requestStack->push($request);
     $this->aliasManager->addAlias('/my/aliased/page', '/my/pass/page');
     $this->assertTrue($condition->execute(), 'The request path matches an aliased path');
     $this->assertEqual($condition->summary(), 'Return true on the following pages: /my/pass/page, /my/pass/page2, /foo', 'The condition summary matches for an aliased path');
     // Test a wildcard path.
     $this->aliasManager->addAlias('/my/pass/page3', '/my/pass/page3');
     $this->currentPath->setPath('/my/pass/page3', $request);
     $this->requestStack->pop();
     $this->requestStack->push($request);
     $condition->setConfig('pages', '/my/pass/*');
     $this->assertTrue($condition->evaluate(), 'The system_path my/pass/page3 passes for wildcard paths.');
     $this->assertEqual($condition->summary(), 'Return true on the following pages: /my/pass/*', 'The condition summary matches for a wildcard path');
     // Test a missing path.
     $this->requestStack->pop();
     $this->requestStack->push($request);
     $this->currentPath->setPath('/my/fail/page4', $request);
     $condition->setConfig('pages', '/my/pass/*');
     $this->aliasManager->addAlias('/my/fail/page4', '/my/fail/page4');
     $this->assertFalse($condition->evaluate(), 'The system_path /my/pass/page4 fails for a missing path.');
     // Test a path of '/'.
     $this->aliasManager->addAlias('/', '/my/pass/page3');
     $this->currentPath->setPath('/', $request);
     $this->requestStack->pop();
     $this->requestStack->push($request);
     $this->assertTrue($condition->evaluate(), 'The system_path my/pass/page3 passes for wildcard paths.');
     $this->assertEqual($condition->summary(), 'Return true on the following pages: /my/pass/*', 'The condition summary matches for a wildcard path');
 }
Example #8
0
 /**
  * renders content with the real website controller.
  *
  * @param PageBridge $content
  * @param bool       $partial
  *
  * @return string
  */
 public function render(PageBridge $content, $partial = false)
 {
     // set active theme
     $webspace = $this->webspaceManager->findWebspaceByKey($content->getWebspaceKey());
     $this->activeTheme->setName($webspace->getTheme()->getKey());
     // get controller and invoke action
     $request = new Request();
     $request->attributes->set('_controller', $content->getController());
     $controller = $this->controllerResolver->getController($request);
     // prepare locale for translator and request
     $request->setLocale($content->getLanguageCode());
     $localeBefore = $this->translator->getLocale();
     $this->translator->setLocale($content->getLanguageCode());
     $this->requestStack->push($request);
     /** @var Response $response */
     $response = $controller[0]->{$controller[1]}($content, true, $partial);
     // roll back
     $this->requestStack->pop();
     $this->translator->setLocale($localeBefore);
     return $response->getContent();
 }
 public function testLegacyResultHasLayout()
 {
     $requestStack = new RequestStack();
     $requestStack->push(new Request());
     $manager = new LegacyResponseManager($this->templateEngine, $this->configResolver, $requestStack);
     self::assertFalse($manager->legacyResultHasLayout(new ezpKernelResult()));
     $resultWithLegacyLayout = new ezpKernelResult('', ['module_result' => ['pagelayout' => 'foo.tpl']]);
     self::assertTrue($manager->legacyResultHasLayout($resultWithLegacyLayout));
     $request = new Request();
     $request->attributes->set('_route', '_ezpublishLegacyLayoutSet');
     $requestStack->pop();
     $requestStack->push($request);
     self::assertTrue($manager->legacyResultHasLayout($resultWithLegacyLayout));
 }
Example #10
0
    /**
     * Sends BigPipe placeholders' replacements as embedded AJAX responses.
     *
     * @param array $placeholders
     *   Associative array; the BigPipe placeholders. Keys are the BigPipe
     *   selectors.
     * @param array $placeholder_order
     *   Indexed array; the order in which the BigPipe placeholders must be sent.
     *   Values are the BigPipe selectors. (These values correspond to keys in
     *   $placeholders.)
     * @param \Drupal\Core\Asset\AttachedAssetsInterface $cumulative_assets
     *   The cumulative assets sent so far; to be updated while rendering BigPipe
     *   placeholders.
     */
    protected function sendPlaceholders(array $placeholders, array $placeholder_order, AttachedAssetsInterface $cumulative_assets)
    {
        // Return early if there are no BigPipe placeholders to send.
        if (empty($placeholders)) {
            return;
        }
        // Send a container and the start signal.
        print "\n";
        print '<script type="application/json" data-big-pipe-event="start"></script>' . "\n";
        flush();
        // A BigPipe response consists of a HTML response plus multiple embedded
        // AJAX responses. To process the attachments of those AJAX responses, we
        // need a fake request that is identical to the master request, but with
        // one change: it must have the right Accept header, otherwise the work-
        // around for a bug in IE9 will cause not JSON, but <textarea>-wrapped JSON
        // to be returned.
        // @see \Drupal\Core\EventSubscriber\AjaxResponseSubscriber::onResponse()
        $fake_request = $this->requestStack->getMasterRequest()->duplicate();
        $fake_request->headers->set('Accept', 'application/json');
        foreach ($placeholder_order as $placeholder) {
            if (!isset($placeholders[$placeholder])) {
                continue;
            }
            // Render the placeholder.
            $placeholder_render_array = $placeholders[$placeholder];
            $elements = $this->renderPlaceholder($placeholder, $placeholder_render_array);
            // Create a new AjaxResponse.
            $ajax_response = new AjaxResponse();
            // JavaScript's querySelector automatically decodes HTML entities in
            // attributes, so we must decode the entities of the current BigPipe
            // placeholder (which has HTML entities encoded since we use it to find
            // the placeholders).
            $big_pipe_js_selector = Html::decodeEntities($placeholder);
            $ajax_response->addCommand(new ReplaceCommand(sprintf('[data-big-pipe-selector="%s"]', $big_pipe_js_selector), $elements['#markup']));
            $ajax_response->setAttachments($elements['#attached']);
            // Push a fake request with the asset libraries loaded so far and dispatch
            // KernelEvents::RESPONSE event. This results in the attachments for the
            // AJAX response being processed by AjaxResponseAttachmentsProcessor and
            // hence:
            // - the necessary AJAX commands to load the necessary missing asset
            //   libraries and updated AJAX page state are added to the AJAX response
            // - the attachments associated with the response are finalized, which
            //   allows us to track the total set of asset libraries sent in the
            //   initial HTML response plus all embedded AJAX responses sent so far.
            $fake_request->request->set('ajax_page_state', ['libraries' => implode(',', $cumulative_assets->getAlreadyLoadedLibraries())] + $cumulative_assets->getSettings()['ajaxPageState']);
            $this->requestStack->push($fake_request);
            $event = new FilterResponseEvent($this->httpKernel, $fake_request, HttpKernelInterface::SUB_REQUEST, $ajax_response);
            $this->eventDispatcher->dispatch(KernelEvents::RESPONSE, $event);
            $ajax_response = $event->getResponse();
            $this->requestStack->pop();
            // Send this embedded AJAX response.
            $json = $ajax_response->getContent();
            $output = <<<EOF
    <script type="application/json" data-big-pipe-placeholder="{$placeholder}" data-drupal-ajax-processor="big_pipe">
    {$json}
    </script>
EOF;
            print $output;
            flush();
            // Another placeholder was rendered and sent, track the set of asset
            // libraries sent so far. Any new settings are already sent; we don't need
            // to track those.
            if (isset($ajax_response->getAttachments()['drupalSettings']['ajaxPageState']['libraries'])) {
                $cumulative_assets->setAlreadyLoadedLibraries(explode(',', $ajax_response->getAttachments()['drupalSettings']['ajaxPageState']['libraries']));
            }
        }
        // Send the stop signal.
        print '<script type="application/json" data-big-pipe-event="stop"></script>' . "\n";
        flush();
    }
 /**
  * @return null|Request
  */
 protected function popRequestFromStack()
 {
     return $this->requestStack->pop();
 }