X-Git-Url: http://aleph1.co.uk/gitweb/?a=blobdiff_plain;ds=inline;f=web%2Fcore%2Fmodules%2Fuser%2Fsrc%2FPlugin%2FBlock%2FUserLoginBlock.php;fp=web%2Fcore%2Fmodules%2Fuser%2Fsrc%2FPlugin%2FBlock%2FUserLoginBlock.php;h=a9341f9b7f7938111598d096d7cae60ed1262dbe;hb=9917807b03b64faf00f6a1f29dcb6eafc454efa5;hp=ed0e2eaf1a8a7e12dac4ab85fe28ff52f50d6609;hpb=aea91e65e895364e460983b890e295aa5d5540a5;p=yaffs-website diff --git a/web/core/modules/user/src/Plugin/Block/UserLoginBlock.php b/web/core/modules/user/src/Plugin/Block/UserLoginBlock.php index ed0e2eaf1..a9341f9b7 100644 --- a/web/core/modules/user/src/Plugin/Block/UserLoginBlock.php +++ b/web/core/modules/user/src/Plugin/Block/UserLoginBlock.php @@ -6,7 +6,6 @@ use Drupal\Core\Access\AccessResult; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\Core\Routing\RedirectDestinationTrait; use Drupal\Core\Routing\RouteMatchInterface; -use Drupal\Core\Routing\UrlGeneratorTrait; use Drupal\Core\Url; use Drupal\Core\Session\AccountInterface; use Drupal\Core\Block\BlockBase; @@ -23,7 +22,6 @@ use Symfony\Component\DependencyInjection\ContainerInterface; */ class UserLoginBlock extends BlockBase implements ContainerFactoryPluginInterface { - use UrlGeneratorTrait; use RedirectDestinationTrait; /** @@ -94,7 +92,24 @@ class UserLoginBlock extends BlockBase implements ContainerFactoryPluginInterfac unset($form['pass']['#attributes']['aria-describedby']); $form['name']['#size'] = 15; $form['pass']['#size'] = 15; - $form['#action'] = $this->url('', [], ['query' => $this->getDestinationArray(), 'external' => FALSE]); + + // Instead of setting an actual action URL, we set the placeholder, which + // will be replaced at the very last moment. This ensures forms with + // dynamically generated action URLs don't have poor cacheability. + // Use the proper API to generate the placeholder, when we have one. See + // https://www.drupal.org/node/2562341. The placholder uses a fixed string + // that is + // Crypt::hashBase64('\Drupal\user\Plugin\Block\UserLoginBlock::build'); + // This is based on the implementation in + // \Drupal\Core\Form\FormBuilder::prepareForm(), but the user login block + // requires different behavior for the destination query argument. + $placeholder = 'form_action_p_4r8ITd22yaUvXM6SzwrSe9rnQWe48hz9k1Sxto3pBvE'; + + $form['#attached']['placeholders'][$placeholder] = [ + '#lazy_builder' => ['\Drupal\user\Plugin\Block\UserLoginBlock::renderPlaceholderFormAction', []], + ]; + $form['#action'] = $placeholder; + // Build action links. $items = []; if (\Drupal::config('user.settings')->get('register') != USER_REGISTER_ADMINISTRATORS_ONLY) { @@ -128,4 +143,20 @@ class UserLoginBlock extends BlockBase implements ContainerFactoryPluginInterfac ]; } + /** + * #lazy_builder callback; renders a form action URL including destination. + * + * @return array + * A renderable array representing the form action. + * + * @see \Drupal\Core\Form\FormBuilder::renderPlaceholderFormAction() + */ + public static function renderPlaceholderFormAction() { + return [ + '#type' => 'markup', + '#markup' => Url::fromRoute('', [], ['query' => \Drupal::destination()->getAsArray(), 'external' => FALSE])->toString(), + '#cache' => ['contexts' => ['url.path', 'url.query_args']], + ]; + } + }