4

When a user presses the "add to cart" button on a product page, I want to automatically redirect the user to the checkout page.

Drupal 7 has an issue for doing this programatically and an issue for doing this with the Rules module.

Rules is still in alpha for D8, and I tried to make a rule that acts on after saving a new order, but I'm getting an error when I try to add an action:

Error: Call to a member function getDataType() on null in Drupal\rules\Plugin\RulesAction\EntityCreateDeriver->getDerivativeDefinitions() (line 99 of modules/contrib/rules/src/Plugin/RulesAction/EntityCreateDeriver.php).

So I want to redirect from add to cart to the checkout page programatically.

But there is no documentation yet. So if anyone can explain how to do this, I would be much obliged.

3

There's an issue here to allow that through the formatter, it has a MR from me that we are using for a project. Note that it skips the cart completely, there is just checkout.

https://www.drupal.org/node/2810723

4

you could do something like this:

use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;

function MYMODULE_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if (strpos($form_id, 'commerce_order_item_add_to_cart_form_commerce_product') !== false) {
    $form['actions']['submit']['#submit'][] = 'MYMODULE_cart_alter_sub';
 }
}
function MYMODULE_cart_alter_sub(&$form, FormStateInterface $form_state) {
  $responce =  new RedirectResponse('/cart');
  $responce->send();
}
2

As there is no rules-based solution yet, I constructed a crappy jquery function to do this.

First, it checks whether Drupal has sent a message that you added a product to your cart, and then performs a simple redirect to the cart page, and there it submits directly to the checkout page.

  Drupal.behaviors.donate = {
    attach: function (context, settings) {
        if ($("div[role=contentinfo]").length){
              var str=$("div[role=contentinfo]").html();
              var n=str.includes('Donatie added to <a href="/cart">your cart</a>.');
              if (n){
                  window.location="/cart";
              }
        }
        if ($("#edit-checkout").length){
               $("#edit-checkout").click();
        }

  }
  }; 
1

Thanks to @Berdir for writing the code for this.

How to use the patch

  1. Apply the patch.
  2. Go to the Product Types -> Edit Display page for your product type that you want to skip the cart for (/admin/commerce/config/product-types/my-product-type/edit/display).
  3. Look for the Product Variations field, the format of which should be Add to cart form. Click the little gear icon on the right.
  4. Check the box for Skip cart and press Update.
1

I also needed this redirect (to the cart, but it could also work for the checkout).

There are a few possibilities that appeared to work, but not predictable:

  • Rules redirect based on saving an order item
  • Event listener on: commerce_order.place.post_transition
  • Submit handler on the 'add to cart' action. All these solutions may appear to work at first sight but after further testing it appeared that the redirect was sometimes done before adding the item to the cart.

Therefore I fall back on the solution given by Egbert Bleyenburg with the difference that I used hook_preprocess_status_messages(). So I skip the step of rendering the status message and don't use the javascript.

Call your function in hook_preprocess_status_messages():

function hook_preprocess_status_messages(&$variables) {
  redirect_order_to_cart($variables['message_list']['status']);
}

Above is just an example, in production you'd like to have a condition to check if you are on the correct page and if the status messages are set. Below the custom function you call to redirect:

function redirect_order_to_cart(array $status_messages) {
  $cart_path = Url::fromRoute('commerce_cart.page')->getInternalPath();

  foreach ($status_messages as $message) {

    // If we have a status message containing a href with the cart path we know
    // that it's the order item confirm message. This is the moment we want to
    // redirect to the cart.
    if (
      $message instanceof Markup
      && strpos($message->jsonSerialize(), 'href="/' . $cart_path) !== FALSE
    ) {
      // Setting the redirect.
      $response = new RedirectResponse(\Drupal::service('url_generator')
        ->generateFromRoute('commerce_cart.page'));
      $response->send();
      break;
    }
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.