Issue #956186 by catch, dpolant, SteffenR, yhahn, lauriii, nod_, sokrplare, rwaery.11, Supreetam09, effulgentsia, geek-merlin: Allow AJAX to use GET requests
parent
d4b5939879
commit
29763eaaf5
|
@ -132,7 +132,7 @@ class AjaxResponseAttachmentsProcessor implements AttachmentsResponseProcessorIn
|
|||
* An array of commands ready to be returned as JSON.
|
||||
*/
|
||||
protected function buildAttachmentsCommands(AjaxResponse $response, Request $request) {
|
||||
$ajax_page_state = $request->request->all('ajax_page_state');
|
||||
$ajax_page_state = $request->get('ajax_page_state');
|
||||
|
||||
// Aggregate CSS/JS if necessary, but only during normal site operation.
|
||||
$optimize_css = !defined('MAINTENANCE_MODE') && $this->config->get('css.preprocess');
|
||||
|
|
|
@ -244,6 +244,7 @@ abstract class RenderElement extends PluginBase implements ElementInterface {
|
|||
* - #ajax['event']
|
||||
* - #ajax['prevent']
|
||||
* - #ajax['url']
|
||||
* - #ajax['type']
|
||||
* - #ajax['callback']
|
||||
* - #ajax['options']
|
||||
* - #ajax['wrapper']
|
||||
|
@ -340,6 +341,7 @@ abstract class RenderElement extends PluginBase implements ElementInterface {
|
|||
// to be substantially different for a JavaScript triggered submission.
|
||||
$settings += [
|
||||
'url' => NULL,
|
||||
'type' => 'POST',
|
||||
'options' => ['query' => []],
|
||||
'dialogType' => 'ajax',
|
||||
];
|
||||
|
|
|
@ -65,7 +65,7 @@ class AjaxBasePageNegotiator implements ThemeNegotiatorInterface {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function applies(RouteMatchInterface $route_match) {
|
||||
$ajax_page_state = $this->requestStack->getCurrentRequest()->request->all('ajax_page_state');
|
||||
$ajax_page_state = $this->requestStack->getCurrentRequest()->get('ajax_page_state');
|
||||
return !empty($ajax_page_state['theme']) && isset($ajax_page_state['theme_token']);
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,7 @@ class AjaxBasePageNegotiator implements ThemeNegotiatorInterface {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function determineActiveTheme(RouteMatchInterface $route_match) {
|
||||
$ajax_page_state = $this->requestStack->getCurrentRequest()->request->all('ajax_page_state');
|
||||
$ajax_page_state = $this->requestStack->getCurrentRequest()->get('ajax_page_state');
|
||||
$theme = $ajax_page_state['theme'];
|
||||
$token = $ajax_page_state['theme_token'];
|
||||
|
||||
|
|
|
@ -325,6 +325,13 @@
|
|||
elementSettings.url = href;
|
||||
elementSettings.event = 'click';
|
||||
}
|
||||
const type = $linkElement.data('ajax-type');
|
||||
/**
|
||||
* In case of setting custom ajax type for link we rewrite ajax.type.
|
||||
*/
|
||||
if (type) {
|
||||
elementSettings.type = type;
|
||||
}
|
||||
Drupal.ajax(elementSettings);
|
||||
});
|
||||
};
|
||||
|
@ -391,6 +398,7 @@
|
|||
*/
|
||||
Drupal.Ajax = function (base, element, elementSettings) {
|
||||
const defaults = {
|
||||
type: 'POST',
|
||||
event: element ? 'mousedown' : null,
|
||||
keypress: true,
|
||||
selector: base ? `#${base}` : null,
|
||||
|
@ -591,7 +599,7 @@
|
|||
},
|
||||
dataType: 'json',
|
||||
jsonp: false,
|
||||
type: 'POST',
|
||||
type: ajax.type,
|
||||
};
|
||||
|
||||
if (elementSettings.dialog) {
|
||||
|
|
|
@ -465,7 +465,7 @@ class BigPipe {
|
|||
// - the HTML to load the CSS can be rendered.
|
||||
// - the HTML to load the JS (at the top) can be rendered.
|
||||
$fake_request = $this->requestStack->getMainRequest()->duplicate();
|
||||
$fake_request->request->set('ajax_page_state', ['libraries' => implode(',', $cumulative_assets->getAlreadyLoadedLibraries())]);
|
||||
$fake_request->query->set('ajax_page_state', ['libraries' => implode(',', $cumulative_assets->getAlreadyLoadedLibraries())]);
|
||||
try {
|
||||
$html_response = $this->filterEmbeddedResponse($fake_request, $html_response);
|
||||
}
|
||||
|
@ -575,7 +575,7 @@ class BigPipe {
|
|||
// - 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']);
|
||||
$fake_request->query->set('ajax_page_state', ['libraries' => implode(',', $cumulative_assets->getAlreadyLoadedLibraries())] + $cumulative_assets->getSettings()['ajaxPageState']);
|
||||
try {
|
||||
$ajax_response = $this->filterEmbeddedResponse($fake_request, $ajax_response);
|
||||
}
|
||||
|
|
|
@ -90,6 +90,7 @@
|
|||
this.element_settings = {
|
||||
url: ajaxPath + queryString,
|
||||
submit: settings,
|
||||
type: 'GET',
|
||||
setClick: true,
|
||||
event: 'click',
|
||||
selector,
|
||||
|
@ -127,6 +128,7 @@
|
|||
const selfSettings = $.extend({}, this.element_settings, {
|
||||
event: 'RefreshView',
|
||||
base: this.selector,
|
||||
type: 'GET',
|
||||
element: this.$view.get(0),
|
||||
});
|
||||
this.refreshViewAjax = Drupal.ajax(selfSettings);
|
||||
|
@ -201,6 +203,7 @@
|
|||
submit: viewData,
|
||||
base: false,
|
||||
element: link,
|
||||
type: 'GET',
|
||||
});
|
||||
this.pagerAjax = Drupal.ajax(selfSettings);
|
||||
};
|
||||
|
|
|
@ -12,8 +12,6 @@ use Drupal\Core\EventSubscriber\AjaxResponseSubscriber;
|
|||
use Drupal\Core\EventSubscriber\MainContentViewSubscriber;
|
||||
use Drupal\Core\Form\FormBuilderInterface;
|
||||
use Drupal\Core\Path\CurrentPathStack;
|
||||
use Drupal\Core\Render\BubbleableMetadata;
|
||||
use Drupal\Core\Render\RenderContext;
|
||||
use Drupal\Core\Render\RendererInterface;
|
||||
use Drupal\Core\Routing\RedirectDestinationInterface;
|
||||
use Drupal\Core\Ajax\ScrollTopCommand;
|
||||
|
@ -112,10 +110,10 @@ class ViewAjaxController implements ContainerInjectionInterface {
|
|||
* Thrown when the view was not found.
|
||||
*/
|
||||
public function ajaxView(Request $request) {
|
||||
$name = $request->request->get('view_name');
|
||||
$display_id = $request->request->get('view_display_id');
|
||||
$name = $request->get('view_name');
|
||||
$display_id = $request->get('view_display_id');
|
||||
if (isset($name) && isset($display_id)) {
|
||||
$args = $request->request->get('view_args', '');
|
||||
$args = $request->get('view_args', '');
|
||||
$args = $args !== '' ? explode('/', Html::decodeEntities($args)) : [];
|
||||
|
||||
// Arguments can be empty, make sure they are passed on as NULL so that
|
||||
|
@ -124,10 +122,10 @@ class ViewAjaxController implements ContainerInjectionInterface {
|
|||
return ($arg == '' ? NULL : $arg);
|
||||
}, $args);
|
||||
|
||||
$path = $request->request->get('view_path');
|
||||
$dom_id = $request->request->get('view_dom_id');
|
||||
$path = $request->get('view_path');
|
||||
$dom_id = $request->get('view_dom_id');
|
||||
$dom_id = isset($dom_id) ? preg_replace('/[^a-zA-Z0-9_-]+/', '-', $dom_id) : NULL;
|
||||
$pager_element = $request->request->get('pager_element');
|
||||
$pager_element = $request->get('pager_element');
|
||||
$pager_element = isset($pager_element) ? intval($pager_element) : NULL;
|
||||
|
||||
$response = new ViewAjaxResponse();
|
||||
|
@ -164,10 +162,9 @@ class ViewAjaxController implements ContainerInjectionInterface {
|
|||
$this->currentPath->setPath('/' . ltrim($path, '/'), $request);
|
||||
}
|
||||
|
||||
// Add all POST data, because AJAX is always a post and many things,
|
||||
// Add all POST data, because AJAX is sometimes a POST and many things,
|
||||
// such as tablesorts, exposed filters and paging assume GET.
|
||||
$request_all = $request->request->all();
|
||||
unset($request_all['ajax_page_state']);
|
||||
$query_all = $request->query->all();
|
||||
$request->query->replace($request_all + $query_all);
|
||||
|
||||
|
@ -190,16 +187,7 @@ class ViewAjaxController implements ContainerInjectionInterface {
|
|||
// Reuse the same DOM id so it matches that in drupalSettings.
|
||||
$view->dom_id = $dom_id;
|
||||
|
||||
$context = new RenderContext();
|
||||
$preview = $this->renderer->executeInRenderContext($context, function () use ($view, $display_id, $args) {
|
||||
return $view->preview($display_id, $args);
|
||||
});
|
||||
if (!$context->isEmpty()) {
|
||||
$bubbleable_metadata = $context->pop();
|
||||
BubbleableMetadata::createFromRenderArray($preview)
|
||||
->merge($bubbleable_metadata)
|
||||
->applyTo($preview);
|
||||
}
|
||||
$preview = $view->preview($display_id, $args);
|
||||
$response->addCommand(new ReplaceCommand(".js-view-dom-id-$dom_id", $preview));
|
||||
$response->addCommand(new PrependCommand(".js-view-dom-id-$dom_id", ['#type' => 'status_messages']));
|
||||
|
||||
|
|
|
@ -157,7 +157,7 @@ class ViewsForm implements FormInterface, ContainerInjectionInterface {
|
|||
$form = [];
|
||||
|
||||
$query = $this->requestStack->getCurrentRequest()->query->all();
|
||||
$query = UrlHelper::filterQueryParameters($query, [], '');
|
||||
$query = UrlHelper::filterQueryParameters($query, ['_wrapper_format'], '');
|
||||
|
||||
$options = ['query' => $query];
|
||||
$form['#action'] = $view->hasUrl() ? $view->getUrl()->setOptions($options)->toString() : Url::fromRoute('<current>')->setOptions($options)->toString();
|
||||
|
|
|
@ -98,8 +98,6 @@ class PaginationAJAXTest extends WebDriverTestBase {
|
|||
$this->assertCount(5, $rows);
|
||||
$this->assertStringContainsString('Node 6 content', $rows[0]->getHtml());
|
||||
$link = $page->findLink('Go to page 3');
|
||||
// Test that no unwanted parameters are added to the URL.
|
||||
$this->assertEquals('?status=All&type=All&langcode=All&items_per_page=5&order=changed&sort=asc&page=2', $link->getAttribute('href'));
|
||||
$this->assertNoDuplicateAssetsOnPage();
|
||||
|
||||
$this->clickLink('Go to page 3');
|
||||
|
|
|
@ -182,18 +182,18 @@ class ViewAjaxControllerTest extends UnitTestCase {
|
|||
*/
|
||||
public function testAjaxView() {
|
||||
$request = new Request();
|
||||
$request->request->set('view_name', 'test_view');
|
||||
$request->request->set('view_display_id', 'page_1');
|
||||
$request->request->set('view_path', '/test-page');
|
||||
$request->request->set('_wrapper_format', 'ajax');
|
||||
$request->request->set('ajax_page_state', 'drupal.settings[]');
|
||||
$request->request->set('type', 'article');
|
||||
$request->query->set('view_name', 'test_view');
|
||||
$request->query->set('view_display_id', 'page_1');
|
||||
$request->query->set('view_path', '/test-page');
|
||||
$request->query->set('_wrapper_format', 'ajax');
|
||||
$request->query->set('ajax_page_state', 'drupal.settings[]');
|
||||
$request->query->set('type', 'article');
|
||||
|
||||
[$view, $executable] = $this->setupValidMocks();
|
||||
|
||||
$this->redirectDestination->expects($this->atLeastOnce())
|
||||
->method('set')
|
||||
->with('/test-page?type=article');
|
||||
->with('/test-page?ajax_page_state=drupal.settings%5B%5D&type=article');
|
||||
$this->currentPath->expects($this->once())
|
||||
->method('setPath')
|
||||
->with('/test-page', $request);
|
||||
|
@ -211,18 +211,18 @@ class ViewAjaxControllerTest extends UnitTestCase {
|
|||
*/
|
||||
public function testAjaxViewViewPathNoSlash() {
|
||||
$request = new Request();
|
||||
$request->request->set('view_name', 'test_view');
|
||||
$request->request->set('view_display_id', 'page_1');
|
||||
$request->request->set('view_path', 'test-page');
|
||||
$request->request->set('_wrapper_format', 'ajax');
|
||||
$request->request->set('ajax_page_state', 'drupal.settings[]');
|
||||
$request->request->set('type', 'article');
|
||||
$request->query->set('view_name', 'test_view');
|
||||
$request->query->set('view_display_id', 'page_1');
|
||||
$request->query->set('view_path', 'test-page');
|
||||
$request->query->set('_wrapper_format', 'ajax');
|
||||
$request->query->set('ajax_page_state', 'drupal.settings[]');
|
||||
$request->query->set('type', 'article');
|
||||
|
||||
[$view, $executable] = $this->setupValidMocks();
|
||||
|
||||
$this->redirectDestination->expects($this->atLeastOnce())
|
||||
->method('set')
|
||||
->with('test-page?type=article');
|
||||
->with('test-page?ajax_page_state=drupal.settings%5B%5D&type=article');
|
||||
$this->currentPath->expects($this->once())
|
||||
->method('setPath')
|
||||
->with('/test-page');
|
||||
|
|
|
@ -55,8 +55,10 @@ class AjaxBasePageNegotiatorTest extends UnitTestCase {
|
|||
* @dataProvider providerTestApplies
|
||||
*/
|
||||
public function testApplies($request_data, $expected) {
|
||||
$request = new Request([], $request_data);
|
||||
$request->request = new InputBag($request->request->all());
|
||||
$request = new Request();
|
||||
foreach ($request_data as $key => $data) {
|
||||
$request->query->set($key, $data);
|
||||
}
|
||||
$route_match = RouteMatch::createFromRequest($request);
|
||||
$this->requestStack->push($request);
|
||||
|
||||
|
@ -80,8 +82,8 @@ class AjaxBasePageNegotiatorTest extends UnitTestCase {
|
|||
$theme = 'claro';
|
||||
$theme_token = 'valid_theme_token';
|
||||
|
||||
$request = new Request([], ['ajax_page_state' => ['theme' => $theme, 'theme_token' => $theme_token]]);
|
||||
$request->request = new InputBag($request->request->all());
|
||||
$request = new Request();
|
||||
$request->query->set('ajax_page_state', ['theme' => $theme, 'theme_token' => $theme_token]);
|
||||
$this->requestStack->push($request);
|
||||
$route_match = RouteMatch::createFromRequest($request);
|
||||
|
||||
|
@ -97,8 +99,8 @@ class AjaxBasePageNegotiatorTest extends UnitTestCase {
|
|||
public function testDetermineActiveThemeInvalidToken() {
|
||||
$theme = 'claro';
|
||||
$theme_token = 'invalid_theme_token';
|
||||
|
||||
$request = new Request([], ['ajax_page_state' => ['theme' => $theme, 'theme_token' => $theme_token]]);
|
||||
$request = new Request();
|
||||
$request->query->set('ajax_page_state', ['theme' => $theme, 'theme_token' => $theme_token]);
|
||||
$request->request = new InputBag($request->request->all());
|
||||
$this->requestStack->push($request);
|
||||
$route_match = RouteMatch::createFromRequest($request);
|
||||
|
@ -118,7 +120,8 @@ class AjaxBasePageNegotiatorTest extends UnitTestCase {
|
|||
// theme token. See system_js_settings_alter().
|
||||
$theme_token = '';
|
||||
|
||||
$request = new Request([], ['ajax_page_state' => ['theme' => $theme, 'theme_token' => $theme_token]]);
|
||||
$request = new Request([]);
|
||||
$request->query->set('ajax_page_state', ['theme' => $theme, 'theme_token' => $theme_token]);
|
||||
$request->request = new InputBag($request->request->all());
|
||||
$this->requestStack->push($request);
|
||||
$route_match = RouteMatch::createFromRequest($request);
|
||||
|
|
Loading…
Reference in New Issue