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 63e6be7..c350ab2 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 63d6063..aaf7713 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 61e9143..bdeb2a6 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,23 @@ class CheckoutProgressBlock extends BlockBase implements ContainerFactoryPluginI continue; } + // Create breadcrumb style links for active checkout steps. + if ( + $configuration['display_checkout_progress_breadcrumb_links'] && + $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 352ee67..8b82efa 100644 --- a/modules/checkout/src/Plugin/Commerce/CheckoutFlow/CheckoutFlowBase.php +++ b/modules/checkout/src/Plugin/Commerce/CheckoutFlow/CheckoutFlowBase.php @@ -235,6 +235,7 @@ abstract class CheckoutFlowBase extends PluginBase implements CheckoutFlowInterf public function defaultConfiguration() { return [ 'display_checkout_progress' => TRUE, + 'display_checkout_progress_breadcrumb_links' => FALSE, ]; } @@ -248,6 +249,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; } @@ -265,6 +272,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 0771032..b0a9276 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 }}
  4. {% endfor %}
diff --git a/modules/checkout/tests/src/Functional/CheckoutOrderTest.php b/modules/checkout/tests/src/Functional/CheckoutOrderTest.php index 04f7b35..54845b8 100644 --- a/modules/checkout/tests/src/Functional/CheckoutOrderTest.php +++ b/modules/checkout/tests/src/Functional/CheckoutOrderTest.php @@ -145,6 +145,10 @@ class CheckoutOrderTest extends CommerceBrowserTestBase { * Tests anonymous and authenticated checkout. */ public function testCheckout() { + $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'); @@ -154,7 +158,15 @@ class CheckoutOrderTest extends CommerceBrowserTestBase { $this->submitForm([], 'Checkout'); $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->assertCheckoutProgressStep('Login'); + $this->submitForm([], 'Continue as Guest'); $this->assertCheckoutProgressStep('Order information'); $this->submitForm([ @@ -169,6 +181,7 @@ class CheckoutOrderTest extends CommerceBrowserTestBase { 'billing_information[profile][address][0][address][administrative_area]' => 'CA', ], 'Continue to review'); $this->assertCheckoutProgressStep('Review'); + $this->assertSession()->elementsCount('css', '.block-commerce-checkout-progress li.checkout-progress--step > a', 2); $this->assertSession()->pageTextContains('Contact information'); $this->assertSession()->pageTextContains('Billing information'); $this->assertSession()->pageTextContains('Order Summary'); @@ -218,6 +231,15 @@ class CheckoutOrderTest extends CommerceBrowserTestBase { $this->submitForm([], 'Continue to review'); $this->assertSession()->pageTextContains('Billing information'); $this->assertSession()->pageTextContains('Order Summary'); + $this->assertSession()->elementsCount('css', '.block-commerce-checkout-progress li.checkout-progress--step > a', 1); + $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->assertSession()->elementsCount('css', '.block-commerce-checkout-progress li.checkout-progress--step > a', 0); + $this->submitForm([], 'Continue to review'); $this->assertCheckoutProgressStep('Review'); // Go back and forth. @@ -262,6 +284,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();