QueryException when deleting payment method due to missing access check in commerce_recurring module on Drupal 10

Created on 7 August 2024, 5 months ago

Problem/Motivation

When attempting to delete a payment method from the edit form, an error occurs due to the missing accessCheck() method in the entity query. This results in a QueryException being thrown, indicating that the entity query must explicitly set whether the query should be access checked or not. The specific error message is:

Drupal\Core\Entity\Query\QueryException: Entity queries must explicitly set whether the query should be access checked or not. See Drupal\Core\Entity\Query\QueryInterface::accessCheck(). in Drupal\Core\Entity\Query\Sql\Query->prepare() (line 141 of /var/www/html/public_html/core/lib/Drupal/Core/Entity/Query/Sql/Query.php).

This issue prevents the successful deletion of the payment method and could potentially disrupt the associated subscriptions.

Steps to reproduce

  1. Go to the user profile with payment methods (e.g., /user/{uid}/payment-methods).
  2. Edit a credit card payment method (e.g., /user/{uid}/payment-methods/{payment_method_id}/edit).
  3. Attempt to delete the payment method from the edit form.
  4. Observe the error message indicating the QueryException.

Proposed resolution

To resolve this issue, add the accessCheck(TRUE) method to the entity query in the commerce_recurring_form_commerce_payment_method_credit_card_delete_form_alter function. The accessCheck(TRUE) method will ensure that the query respects access permissions.

Here is the updated code snippet with the proposed change:

public_html\modules\contrib\commerce_recurring\commerce_recurring.module L112
/**
 * Implements hook_form_FORM_ID_alter() for 'commerce_payment_method_credit_card_delete_form'.
 */
function commerce_recurring_form_commerce_payment_method_credit_card_delete_form_alter(array &$form, FormStateInterface $form_state) {
  if (empty($form_state->getUserInput()) && !$form_state->isRebuilding()) {
    /** @var \Drupal\commerce_payment\Entity\PaymentMethodInterface $payment_method */
    $payment_method = $form_state->getFormObject()->getEntity();

    $commerce_subscription_storage_handler = \Drupal::entityTypeManager()
      ->getStorage('commerce_subscription');
    $query = $commerce_subscription_storage_handler->getQuery()
      //->accessCheck(TRUE) // This is missing
      ->condition('payment_method', $payment_method->id());
    $subscription_ids = $query->execute();
    if ($subscription_ids) {
      $subscriptions = $commerce_subscription_storage_handler->loadMultiple($subscription_ids);
      foreach ($subscriptions as $subscription) {
        \Drupal::messenger()->addWarning(t('Deleting this payment method may cause issues with the associated subscription %subscription. <a href=":url">Please update the payment method for the subscription</a> prior to deletion.', [
          '%subscription' => $subscription->label(),
          ':url' => $subscription->toUrl('customer-edit-form')->toString(),
        ]));
      }
    }
  }
}

Remaining tasks

  1. Update the code to include accessCheck(TRUE) in the entity query.
  2. Test the updated code to ensure the error is resolved and the payment method can be deleted without issues.
  3. Review and merge the changes into the main codebase.
🐛 Bug report
Status

Closed: duplicate

Component

Code

Created by

🇨🇷Costa Rica thony1199

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Production build 0.71.5 2024