0

I've been working with Drupal 7 for a couple of years but am new to Drupal 8, and am just getting into building custom modules.

What I have built is a module that alters Drupal Commerce in order to make it work smoother for sponsoring children (so that it doesn't feel like you are buying children).

It does a couple of things: 1. If you add a second product to the cart, it deletes your old cart. 2. After clicking add to cart, it redirects you to an information page. 3. That page contains a module-generated block with a "continue" button that takes the customer to checkout.

The issue I am hitting is that the code which generates the checkout button block is getting cached, and is pulling an old, no longer existing order ID number.

Is there a way to prevent the block from getting cached, or a better way to programmatically set up a custom block?

Here is my code:

\src\Plugin\Block\ContinueCheckoutBlock.php

<?php
/**
 * @file
 * Contains \Drupal\commerce_custom\Plugin\Block\ContinueCheckoutBlock.
 */
namespace Drupal\commerce_custom\Plugin\Block;
use Drupal\Core\Block\BlockBase;
use Symfony\Component\HttpFoundation;

/**
 * Provides a 'Continue Checkout' block.
 *
 * @Block(
 *   id = "continue_checkout",
 *   admin_label = @Translation("Continue Checkout"),
 *   category = @Translation("Continue Checkout Custom Block")
 * )
 */
class ContinueCheckoutBlock extends BlockBase {
  /**
   * {@inheritdoc}
   */

   public function build() {

      $user = \Drupal::currentUser()->id();
        $connection = \Drupal::database();
    $user_ip = \Drupal::request()->getClientIp();
        $query = $connection->query("select * from commerce_order_item join commerce_order on commerce_order_item.order_id = commerce_order.order_id where uid = :user and state = 'draft' and commerce_order.ip_address = :user_ip order by commerce_order.changed asc limit 1", [':user' => $user, ':user_ip' => $user_ip]);
        $result = $query->fetchAll();
        $order_id = $result[0]->order_id;
    drupal_set_message($order_id);

        return array(
            '#type' =>'markup',
            '#markup' => '<a href=checkout/' . $order_id . '/login class=button>Continue</a>',
            '#cache' => array('max_age'=> 0),
        );
   }
}

commerce_custom.module

<?php

use Drupal\Core\Form\FormStateInterface;
use Drupal\commerce_order\Entity\Order;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation;

/**
 * Implements hook_form_FORM_ID_alter().
 */
function commerce_custom_form_commerce_order_item_add_to_cart_form_alter(&$form, FormStateInterface $form_state, $form_id) {
   $form['actions']['submit']['#value']='Sponsor';
   $form['#validate'][] = 'commerce_custom_form_validate';
   $form['actions']['submit']['#submit'][] = 'commerce_custom_cart_alter_redirect';
}

function commerce_custom_form_validate(array &$form, FormStateInterface $form_state) {

    $user = \Drupal::currentUser()->id();
    $connection = \Drupal::database();
    $user_ip = \Drupal::request()->getClientIp();
    $query = $connection->query("select * from commerce_order_item join commerce_order on commerce_order_item.order_id = commerce_order.order_id where uid = :user and state = 'draft' and commerce_order.ip_address = :user_ip order by commerce_order.changed desc limit 1", [':user' => $user, ':user_ip' => $user_ip]);
    $result = $query->fetchAll();

    $cart_count = $result[0]->quantity;
    $order_id = $result[0]->order_id;

    if ($cart_count > 0 && $order_id) {
        $order = \Drupal::entityTypeManager()->getStorage('commerce_order')->load($order_id);
        $items = $order->getItems();
        $order->delete();
    }
}

function commerce_custom_cart_alter_redirect(&$form, FormStateInterface $form_state) {
  $responce =  new RedirectResponse('/how-it-works');
  $responce->send();
}
1

The bug is in your code. max_age should actually be max-age.

See the documentation page for more information: https://www.drupal.org/docs/8/api/cache-api/cache-max-age

You could also set the max age in Jdrupal's answer.

|improve this answer|||||
  • that worked, thanks! – Kimberlie Davis Jun 24 '19 at 18:27
  • That works, but wouldn't the "correct" way be to define the getCacheMaxAge method? – user72672 Jun 24 '19 at 18:33
  • 1
    @Jdrupal, "correct" would be to place the cache metadata as close as possible to the data it is connected to. If you put data in a render array then place the cache metadata in the same render array. For nested arrays you can bubble up metadata from multiple places. The block plugin implements the same cache interface like any other plugin type and the methods to return cache metadata are mainly used in plugins which don't return rendered output. – 4k4 Jun 24 '19 at 21:15
0
public function getCacheMaxAge() {
    return 0;
}


Add the above code after block's build function.

|improve this answer|||||

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.