Issue #1983164 by dawehner, larowlan: Entity Forms in ajax requests don't find the route.

8.0.x
Alex Pott 2013-06-05 11:24:59 +01:00
parent 99861e89d4
commit 7166d89041
10 changed files with 146 additions and 13 deletions

View File

@ -48,6 +48,9 @@ class AjaxController extends ContainerAware {
// Remove the accept header so the subrequest does not end up back in this
// controller.
$request->headers->remove('accept');
// Remove the header in order to let the subrequest not think that it's an
// ajax request, see \Drupal\Core\ContentNegotiation.
$request->headers->remove('x-requested-with');
$response = $this->container->get('http_kernel')->forward($controller, $attributes->all(), $request->query->all());
// For successful (HTTP status 200) responses.

View File

@ -63,8 +63,7 @@ class HtmlFormController implements ContainerAwareInterface {
$form_state['build_info']['args'] = $args;
$form_id = _drupal_form_id($form_object, $form_state);
$form = drupal_build_form($form_id, $form_state);
return new Response(drupal_render_page($form));
return drupal_build_form($form_id, $form_state);
}
/**

View File

@ -64,18 +64,21 @@ class HttpKernel extends BaseHttpKernel
/**
* Forwards the request to another controller.
*
* @param string $controller The controller name (a string like BlogBundle:Post:index)
* @param array $attributes An array of request attributes
* @param array $query An array of request query parameters
* @param string|NULL $controller
* The controller name (a string like BlogBundle:Post:index).
* @param array $attributes
* An array of request attributes.
* @param array $query
* An array of request query parameters.
*
* @return Response A Response instance
* @return Response
* A Response instance
*/
public function forward($controller, array $attributes = array(), array $query = array())
{
$attributes['_controller'] = $controller;
$subRequest = $this->container->get('request')->duplicate($query, null, $attributes);
$subrequest = $this->setupSubrequest($controller, $attributes, $query);
return $this->handle($subRequest, HttpKernelInterface::SUB_REQUEST);
return $this->handle($subrequest, HttpKernelInterface::SUB_REQUEST);
}
/**
@ -240,4 +243,29 @@ class HttpKernel extends BaseHttpKernel
{
return $this->esiSupport;
}
/**
* Creates a request object for a subrequest.
*
* @param string $controller
* The controller name (a string like BlogBundle:Post:index)
* @param array $attributes
* An array of request attributes.
* @param array $query
* An array of request query parameters.
*
* @return \Symfony\Component\HttpFoundation\Request
* Returns the new request.
*/
public function setupSubrequest($controller, array $attributes, array $query) {
// Don't override the controller if it's NULL.
if (isset($controller)) {
$attributes['_controller'] = $controller;
}
else {
unset($attributes['_controller']);
}
return $this->container->get('request')->duplicate($query, NULL, $attributes);
}
}

View File

@ -38,7 +38,7 @@ class AjaxEnhancer implements RouteEnhancerInterface {
*/
public function enhance(array $defaults, Request $request) {
if (empty($defaults['_content']) && $this->negotiation->getContentType($request) == 'drupal_ajax') {
$defaults['_content'] = $defaults['_controller'];
$defaults['_content'] = isset($defaults['_controller']) ? $defaults['_controller'] : NULL;
$defaults['_controller'] = '\Drupal\Core\Controller\AjaxController::content';
}
return $defaults;

View File

@ -65,4 +65,18 @@ class PreviewTest extends UITestBase {
$this->assertEqual(count($elements), 0);
}
/**
* Tests the actual preview response.
*/
public function testPreviewController() {
$result = $this->drupalGetAJAX('admin/structure/views/view/test_preview/preview/default');
$result_commands = array();
// Build a list of the result commands keyed by the js command.
foreach ($result as $command) {
$result_commands[$command['command']] = $command;
}
$this->assertTrue(isset($result_commands['insert']));
}
}

View File

@ -88,7 +88,7 @@ class ViewPreviewFormController extends ViewFormControllerBase implements Entity
$args = explode('/', $form_state['values']['view_args']);
}
if ($view->renderPreview) {
if (!empty($form_state['show_preview'])) {
$form['preview'] = array(
'#weight' => 110,
'#theme_wrappers' => array('container'),
@ -138,7 +138,6 @@ class ViewPreviewFormController extends ViewFormControllerBase implements Entity
$new_view = new ViewUI($view);
}
$form_state['build_info']['args'][0] = $new_view;
$view->renderPreview = TRUE;
$form_state['show_preview'] = TRUE;
$form_state['rebuild'] = TRUE;
}

View File

@ -534,6 +534,7 @@ class ViewUI implements ViewStorageInterface {
$output = '';
$errors = $this->executable->validate();
$this->executable->destroy();
if (empty($errors)) {
$this->ajax = TRUE;
$this->executable->live_preview = TRUE;

View File

@ -461,5 +461,5 @@ function template_preprocess_views_ui_view_preview_section(&$vars) {
function theme_views_ui_view_preview_section($vars) {
return '<h1 class="section-title">' . $vars['title'] . '</h1>'
. $vars['links']
. '<div class="preview-section">'. $vars['content'] . '</div>';
. '<div class="preview-section">'. drupal_render($vars['content']) . '</div>';
}

View File

@ -0,0 +1,24 @@
<?php
/**
* @file
* Contains \Drupal\Tests\Core\Controller\TestController.
*/
namespace Drupal\Tests\Core\Controller;
use Symfony\Component\HttpFoundation\Response;
/**
* Defines a test controller used by unit tests.
*/
class TestController {
/**
* Returns test content for unit tests.
*/
public function content() {
return new Response('');
}
}

View File

@ -0,0 +1,65 @@
<?php
/**
* @file
* Contains \Drupal\Tests\Core\HttpKernelTest.
*/
namespace Drupal\Tests\Core;
use Drupal\Core\Controller\ControllerResolver;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\HttpKernel;
use Drupal\Tests\UnitTestCase;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
use Symfony\Component\DependencyInjection\Scope;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\KernelEvents;
/**
* Tests the custom http kernel of drupal.
*
* @see \Drupal\Core\HttpKernel
*/
class HttpKernelTest extends UnitTestCase {
public static function getInfo() {
return array(
'name' => 'HttpKernel (Unit)',
'description' => 'Tests the HttpKernel.',
'group' => 'Routing',
);
}
/**
* Tests the forward method.
*
* @see \Drupal\Core\HttpKernel::setupSubrequest()
*/
public function testSetupSubrequest() {
$container = new ContainerBuilder();
$request = new Request();
$container->addScope(new Scope('request'));
$container->enterScope('request');
$container->set('request', $request, 'request');
$dispatcher = new EventDispatcher();
$controller_resolver = new ControllerResolver($container);
$http_kernel = new HttpKernel($dispatcher, $container, $controller_resolver);
$test_controller = '\Drupal\Tests\Core\Controller\TestController';
$random_attribute = $this->randomName();
$subrequest = $http_kernel->setupSubrequest($test_controller, array('custom_attribute' => $random_attribute), array('custom_query' => $random_attribute));
$this->assertNotSame($subrequest, $request, 'The subrequest is not the same as the main request.');
$this->assertEquals($subrequest->attributes->get('custom_attribute'), $random_attribute, 'Attributes are set from the subrequest.');
$this->assertEquals($subrequest->query->get('custom_query'), $random_attribute, 'Query attributes are set from the subrequest.');
$this->assertEquals($subrequest->attributes->get('_controller'), $test_controller, 'Controller attribute got set.');
$subrequest = $http_kernel->setupSubrequest(NULL, array(), array());
$this->assertFalse($subrequest->attributes->has('_controller'), 'Ensure that _controller is not copied when no controller was set before.');
}
}