diff --git a/modules/checkout/config/install/commerce_checkout.commerce_checkout_flow.default.yml b/modules/checkout/config/install/commerce_checkout.commerce_checkout_flow.default.yml index afe25e7e..1b74ee81 100644 --- a/modules/checkout/config/install/commerce_checkout.commerce_checkout_flow.default.yml +++ b/modules/checkout/config/install/commerce_checkout.commerce_checkout_flow.default.yml @@ -6,6 +6,7 @@ label: Default plugin: multistep_default configuration: display_checkout_progress: true + display_checkout_progress_breadcrumb_links: false panes: login: allow_guest_checkout: true diff --git a/modules/checkout/config/schema/commerce_checkout.schema.yml b/modules/checkout/config/schema/commerce_checkout.schema.yml index c0507620..2c6b3c92 100644 --- a/modules/checkout/config/schema/commerce_checkout.schema.yml +++ b/modules/checkout/config/schema/commerce_checkout.schema.yml @@ -38,6 +38,9 @@ commerce_checkout_flow_with_panes_configuration: display_checkout_progress: type: boolean label: 'Display checkout progress' + display_checkout_progress_breadcrumb_links: + type: boolean + label: 'Display checkout progress breadcrumb links' order_summary_view: type: string label: 'Order summary view' diff --git a/modules/checkout/src/Plugin/Block/CheckoutProgressBlock.php b/modules/checkout/src/Plugin/Block/CheckoutProgressBlock.php index 61e9143c..3a743162 100644 --- a/modules/checkout/src/Plugin/Block/CheckoutProgressBlock.php +++ b/modules/checkout/src/Plugin/Block/CheckoutProgressBlock.php @@ -4,6 +4,7 @@ namespace Drupal\commerce_checkout\Plugin\Block; use Drupal\commerce_checkout\CheckoutOrderManagerInterface; use Drupal\Core\Block\BlockBase; +use Drupal\Core\Link; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\Core\Routing\RouteMatchInterface; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -109,9 +110,20 @@ class CheckoutProgressBlock extends BlockBase implements ContainerFactoryPluginI continue; } + // Create breadcrumb style links for active checkout steps. + if ($index <= $current_step_index) { + $label = Link::createFromRoute($step_definition['label'], 'commerce_checkout.form', [ + 'commerce_order' => $order->id(), + 'step' => $step_id, + ])->toString(); + } + else { + $label = $step_definition['label']; + } + $steps[] = [ 'id' => $step_id, - 'label' => $step_definition['label'], + 'label' => $label, 'position' => $position, ]; } diff --git a/modules/checkout/src/Plugin/Commerce/CheckoutFlow/CheckoutFlowBase.php b/modules/checkout/src/Plugin/Commerce/CheckoutFlow/CheckoutFlowBase.php index e2ce53bb..88210da4 100644 --- a/modules/checkout/src/Plugin/Commerce/CheckoutFlow/CheckoutFlowBase.php +++ b/modules/checkout/src/Plugin/Commerce/CheckoutFlow/CheckoutFlowBase.php @@ -200,6 +200,7 @@ abstract class CheckoutFlowBase extends PluginBase implements CheckoutFlowInterf public function defaultConfiguration() { return [ 'display_checkout_progress' => TRUE, + 'display_checkout_progress_breadcrumb_links' => FALSE, ]; } @@ -213,6 +214,12 @@ abstract class CheckoutFlowBase extends PluginBase implements CheckoutFlowInterf '#description' => $this->t('Used by the checkout progress block to determine visibility.'), '#default_value' => $this->configuration['display_checkout_progress'], ]; + $form['display_checkout_progress_breadcrumb_links'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Display checkout progress breadcrumb as links'), + '#description' => $this->t('Let the checkout progress block render the breadcrumb as links.'), + '#default_value' => $this->configuration['display_checkout_progress_breadcrumb_links'], + ]; return $form; } @@ -230,6 +237,7 @@ abstract class CheckoutFlowBase extends PluginBase implements CheckoutFlowInterf $values = $form_state->getValue($form['#parents']); $this->configuration = []; $this->configuration['display_checkout_progress'] = $values['display_checkout_progress']; + $this->configuration['display_checkout_progress_breadcrumb_links'] = $values['display_checkout_progress_breadcrumb_links']; } } diff --git a/modules/checkout/templates/commerce-checkout-progress.html.twig b/modules/checkout/templates/commerce-checkout-progress.html.twig index 07710324..1194b07e 100644 --- a/modules/checkout/templates/commerce-checkout-progress.html.twig +++ b/modules/checkout/templates/commerce-checkout-progress.html.twig @@ -14,6 +14,6 @@ #}
    {% for step in steps %} -
  1. {{ step.label }}
  2. +
  3. {{ step.label | raw }}
  4. {% endfor %}
diff --git a/modules/checkout/tests/src/Functional/CheckoutOrderTest.php b/modules/checkout/tests/src/Functional/CheckoutOrderTest.php index 49d10a3f..4019b4d7 100644 --- a/modules/checkout/tests/src/Functional/CheckoutOrderTest.php +++ b/modules/checkout/tests/src/Functional/CheckoutOrderTest.php @@ -87,8 +87,7 @@ class CheckoutOrderTest extends CommerceBrowserTestBase { $this->drupalGet($this->product->toUrl()); $this->submitForm([], 'Add to cart'); $this->assertSession()->pageTextContains('1 item'); - $cart_link = $this->getSession()->getPage()->findLink('your cart'); - $cart_link->click(); + $this->getSession()->getPage()->findLink('your cart')->click(); $this->submitForm([], 'Checkout'); $this->assertSession()->pageTextNotContains('Order Summary'); $this->assertCheckoutProgressStep('Login'); @@ -138,6 +137,10 @@ class CheckoutOrderTest extends CommerceBrowserTestBase { * Tests than an order can go through checkout steps. */ public function testGuestOrderCheckout() { + $config = \Drupal::configFactory()->getEditable('commerce_checkout.commerce_checkout_flow.default'); + $config->set('configuration.display_checkout_progress_breadcrumb_links', TRUE); + $config->save(); + $this->drupalLogout(); $this->drupalGet($this->product->toUrl()); $this->submitForm([], 'Add to cart'); @@ -177,7 +180,15 @@ class CheckoutOrderTest extends CommerceBrowserTestBase { $this->submitForm([], 'Checkout'); $this->assertCheckoutProgressStep('Login'); $this->assertSession()->pageTextNotContains('Order Summary'); + // Check breadcrumbs are links. + $this->assertSession()->elementsCount('css', '.block-commerce-checkout-progress li.checkout-progress--step > a', 0); $this->submitForm([], 'Continue as Guest'); + // Check breadcrumb link functionality. + $this->assertSession()->elementsCount('css', '.block-commerce-checkout-progress li.checkout-progress--step > a', 1); + $this->getSession()->getPage()->findLink('Login')->click(); + $this->assertSession()->pageTextNotContains('Order Summary'); + $this->submitForm([], 'Continue as Guest'); + $this->assertSession()->pageTextContains('Order Summary'); $this->assertCheckoutProgressStep('Order information'); $this->submitForm([ 'contact_information[email]' => 'guest@example.com', @@ -193,7 +204,23 @@ class CheckoutOrderTest extends CommerceBrowserTestBase { $this->assertSession()->pageTextContains('Contact information'); $this->assertSession()->pageTextContains('Billing information'); $this->assertSession()->pageTextContains('Order Summary'); + $this->assertSession()->elementsCount('css', '.block-commerce-checkout-progress li.checkout-progress--step > a', 2); $this->assertCheckoutProgressStep('Review'); + // Go back with the breadcrumb. + $this->getSession()->getPage()->findLink('Order information')->click(); + $this->assertSession()->pageTextContains('Order Summary'); + $this->assertCheckoutProgressStep('Order information'); + $this->submitForm([ + 'contact_information[email]' => 'guest@example.com', + 'contact_information[email_confirm]' => 'guest@example.com', + 'billing_information[profile][address][0][address][given_name]' => $this->randomString(), + 'billing_information[profile][address][0][address][family_name]' => $this->randomString(), + 'billing_information[profile][address][0][address][organization]' => $this->randomString(), + 'billing_information[profile][address][0][address][address_line1]' => $this->randomString(), + 'billing_information[profile][address][0][address][postal_code]' => '94043', + 'billing_information[profile][address][0][address][locality]' => 'Mountain View', + 'billing_information[profile][address][0][address][administrative_area]' => 'CA', + ], 'Continue to review'); // Go back and forth. $this->getSession()->getPage()->clickLink('Go back'); @@ -204,6 +231,7 @@ class CheckoutOrderTest extends CommerceBrowserTestBase { $this->submitForm([], 'Complete checkout'); $this->assertSession()->pageTextContains('Your order number is 2. You can view your order on your account page when logged in.'); $this->assertSession()->pageTextContains('0 items'); + } /** @@ -229,6 +257,8 @@ class CheckoutOrderTest extends CommerceBrowserTestBase { 'login[register][password][pass2]' => 'pass', ], 'Create account and continue'); $this->assertSession()->pageTextContains('Billing information'); + // Check breadcrumbs are not links. (the default setting) + $this->assertSession()->elementNotExists('css', '.block-commerce-checkout-progress li.checkout-progress--step > a'); // Test account validation. $this->drupalLogout(); @@ -318,8 +348,7 @@ class CheckoutOrderTest extends CommerceBrowserTestBase { $this->drupalLogout(); $this->drupalGet($this->product->toUrl()->toString()); $this->submitForm([], 'Add to cart'); - $cart_link = $this->getSession()->getPage()->findLink('your cart'); - $cart_link->click(); + $this->getSession()->getPage()->findLink('your cart')->click(); $this->submitForm([], 'Checkout'); $this->assertSession()->pageTextContains('New Customer'); $this->submitForm([