Issue #3018942 by welly, alexpott, jibran, Krzysztof Domański, floydm: Domain URL language detection - InvalidArgumentException: The user-entered string must begin with a '/', '?', or '#'

8.7.x
Nathaniel Catchpole 2019-01-02 09:56:15 +00:00
parent b942654652
commit 79e94b49b3
3 changed files with 45 additions and 47 deletions

View File

@ -193,6 +193,9 @@ class BlockListBuilder extends ConfigEntityListBuilder implements FormInterface
if ($this->request->query->has('block-placement')) {
$placement = $this->request->query->get('block-placement');
$form['#attached']['drupalSettings']['blockPlacement'] = $placement;
// Remove the block placement from the current request so that it is not
// passed on to any redirect destinations.
$this->request->query->remove('block-placement');
}
// Loop over each region and build blocks.
@ -354,23 +357,6 @@ class BlockListBuilder extends ConfigEntityListBuilder implements FormInterface
if (isset($operations['delete'])) {
$operations['delete']['title'] = $this->t('Remove');
// Block operation links should have the `block-placement` query string
// parameter removed to ensure that JavaScript does not receive a block
// name that has been recently removed.
foreach ($operations as $operation) {
/** @var \Drupal\Core\Url $url */
$url = $operation['url'];
$query = $url->getOption('query');
$destination = $query['destination'];
$destinationUrl = Url::fromUserInput($destination);
$destinationQuery = $destinationUrl->getOption('query');
unset($destinationQuery['block-placement']);
$destinationUrl->setOption('query', $destinationQuery);
$query['destination'] = $destinationUrl->toString();
$url->setOption('query', $query);
}
}
return $operations;
}
@ -395,9 +381,6 @@ class BlockListBuilder extends ConfigEntityListBuilder implements FormInterface
$entity->save();
}
$this->messenger->addStatus($this->t('The block settings have been updated.'));
// Remove any previously set block placement.
$this->request->query->remove('block-placement');
}
/**

View File

@ -238,30 +238,6 @@ class BlockTest extends BlockTestBase {
$this->assertNoRaw($block->id());
}
/**
* Tests the block operation links.
*/
public function testBlockOperationLinks() {
$this->drupalGet('admin/structure/block');
// Go to the select block form.
$this->clickLink('Place block');
// Select the first available block.
$this->clickLink('Place block');
// Finally place the block
$this->submitForm([], 'Save block');
$url = $this->getUrl();
$parsed = parse_url($url);
$this->assertContains('block-placement', $parsed['query']);
$this->clickLink('Remove');
$this->submitForm([], 'Remove');
$url = $this->getUrl();
$parsed = parse_url($url);
$this->assertTrue(empty($parsed['query']));
}
/**
* Tests that the block form has a theme selector when not passed via the URL.
*/

View File

@ -3,6 +3,8 @@
namespace Drupal\Tests\block\Functional;
use Drupal\Component\Utility\Html;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationUrl;
use Drupal\Tests\BrowserTestBase;
/**
@ -288,6 +290,24 @@ class BlockUiTest extends BrowserTestBase {
* Tests the block placement indicator.
*/
public function testBlockPlacementIndicator() {
// Test the block placement indicator with using the domain as URL language
// indicator. This causes destination query parameters to be absolute URLs.
\Drupal::service('module_installer')->install(['language', 'locale']);
$this->container = \Drupal::getContainer();
ConfigurableLanguage::createFromLangcode('it')->save();
$config = $this->config('language.types');
$config->set('negotiation.language_interface.enabled', [
LanguageNegotiationUrl::METHOD_ID => -10,
]);
$config->save();
$config = $this->config('language.negotiation');
$config->set('url.source', LanguageNegotiationUrl::CONFIG_DOMAIN);
$config->set('url.domains', [
'en' => \Drupal::request()->getHost(),
'it' => 'it.example.com',
]);
$config->save();
// Select the 'Powered by Drupal' block to be placed.
$block = [];
$block['id'] = strtolower($this->randomMachineName());
@ -296,11 +316,30 @@ class BlockUiTest extends BrowserTestBase {
// After adding a block, it will indicate which block was just added.
$this->drupalPostForm('admin/structure/block/add/system_powered_by_block', $block, t('Save block'));
$this->assertUrl('admin/structure/block/list/classy?block-placement=' . Html::getClass($block['id']));
$this->assertSession()->addressEquals('admin/structure/block/list/classy?block-placement=' . Html::getClass($block['id']));
// Resaving the block page will remove the block indicator.
// Resaving the block page will remove the block placement indicator.
$this->drupalPostForm(NULL, [], t('Save blocks'));
$this->assertUrl('admin/structure/block/list/classy');
$this->assertSession()->addressEquals('admin/structure/block/list/classy');
// Place another block and test the remove functionality works with the
// block placement indicator. Click the first 'Place block' link to bring up
// the list of blocks to place in the first available region.
$this->clickLink('Place block');
// Select the first available block.
$this->clickLink('Place block');
$block = [];
$block['id'] = strtolower($this->randomMachineName());
$block['theme'] = 'classy';
$this->submitForm([], 'Save block');
$this->assertSession()->addressEquals('admin/structure/block/list/classy?block-placement=' . Html::getClass($block['id']));
// Removing a block will remove the block placement indicator.
$this->clickLink('Remove');
$this->submitForm([], 'Remove');
// @todo https://www.drupal.org/project/drupal/issues/2980527 this should be
// 'admin/structure/block/list/classy' but there is a bug.
$this->assertSession()->addressEquals('admin/structure/block');
}
/**