commerce_cart_skip-1.0.x-dev/commerce_cart_skip.module

commerce_cart_skip.module
<?php

use Drupal\commerce_cart\Form\AddToCartFormInterface;
use Drupal\commerce_order\Entity\Order;
use Drupal\commerce_order\Entity\OrderItem;
use Drupal\commerce_price\Price;
use Drupal\commerce_product\Entity\ProductVariation;
use Drupal\commerce_product\Entity\ProductVariationInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
use Drupal\profile\Entity\Profile;
use Drupal\user\Entity\User;
use Symfony\Component\HttpFoundation\RedirectResponse;

function commerce_cart_skip_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if ($form_state->getBuildInfo()['callback_object'] instanceof AddToCartFormInterface) {
    commerce_cart_skip_form_alter_add_to_cart($form, $form_state);
  }
}

function commerce_cart_skip_get_rules() {
  $storage = Drupal::entityTypeManager()
    ->getStorage('commerce_cart_skip_rule');
  $commerce_cart_skip_rules = $storage->loadByProperties(['enabled' => TRUE]);
  return $commerce_cart_skip_rules;
}

function commerce_cart_skip_can_skip($rule, ProductVariationInterface $productVariation, $account) {
  $conditions = [];

  if (isset($rule->get('conditions')['commerce_product_variation_type']) && $rule->get('conditions')['commerce_product_variation_type'] != '') {
    $conditions['commerce_product_variation_type'] = $productVariation->bundle() == $rule->get('conditions')['commerce_product_variation_type'];
  }

  if (isset($rule->get('conditions')['commerce_product_type']) && $rule->get('conditions')['commerce_product_type'] != '') {
    $conditions['commerce_product_type'] = $productVariation->getProduct()
        ->bundle() == $rule->get('conditions')['commerce_product_type'];
  }

  if (isset($rule->get('conditions')['price']) && !empty($rule->get('conditions')['price']) && $productVariation->getPrice()) {
    $conditions['price'] = $productVariation->getPrice()
        ->getNumber() == $rule->get('conditions')['price']['number'];
  }

  if (isset($rule->get('conditions')['authenticated']) && $rule->get('conditions')['authenticated']) {
    $conditions['authenticated'] = Drupal::currentUser()->isAuthenticated();
  }

  foreach ($conditions as $value) {
    if (!$value) {
      return FALSE;
    }
  }
  return TRUE;
}

function commerce_cart_skip_form_alter_add_to_cart(&$form, FormStateInterface $form_state) {
  $selectedVariation = commerce_cart_skip_get_variation($form, $form_state);

  if ($selectedVariation) {
    $account = User::load(Drupal::currentUser()->id());
    $rules = commerce_cart_skip_get_rules();
    foreach ($rules as $rule) {
      if (!commerce_cart_skip_can_skip($rule, $selectedVariation, $account)) {
        continue;
      }
      $alreadyPurchased = commerce_cart_skip_user_has_purchased_variation($account, $selectedVariation);

      $context = [
        'rule' => $rule,
        'selectedVariation' => $selectedVariation,
        'account' => $account,
      ];
      Drupal::moduleHandler()
        ->alter(['commerce_cart_skip_already_purchased'], $alreadyPurchased, $context);

      unset($form['quantity']);

      if ($alreadyPurchased) {
        commerce_cart_skip_form_alter_add_to_cart_bought($rule, $form, $form_state);
      }
      else {
        commerce_cart_skip_form_alter_add_to_cart_buy($rule, $form, $form_state);
      }
    }
  }
}

function commerce_cart_skip_get_order($form, $form_state) {
  $selectedVariation = commerce_cart_skip_get_variation($form, $form_state);
  $account = User::load(Drupal::currentUser()->id());
  $ids = commerce_cart_skip_user_has_purchased_variation($account, $selectedVariation, TRUE);
  $orderItem = OrderItem::load($ids[0]);
  return $orderItem->getOrder();
}

function commerce_cart_skip_form_alter_add_to_cart_bought($rule, &$form, FormStateInterface $form_state) {
  $form['bought_message'] = [
    '#weight' => 25,
    '#markup' => $rule->get('ui')['button_bought'] ?? 'Already purchased.',
  ];

  $order = commerce_cart_skip_get_order($form, $form_state);
  if ($order) {
    $url = Url::fromRoute('entity.commerce_order.user_view', [
      'commerce_order' => $order->id(),
      'user' => $order->getCustomerId(),
    ], [])->toString();

    $form['bought_order_link'] = [
      '#weight' => 25,
      '#markup' => '<p><a class="button" href="' . $url . '" target="_blank">' . t($rule->get('ui')['bought_link_text'] ?? 'View order') . '</a></p>',
    ];
  }

  if ($rule->get('allow_cancel') && $rule->get('allow_cancel') == 1) {
    $form['actions']['submit-cancel']['#type'] = 'submit';
    $form['actions']['submit-cancel']['#value'] = t($rule->get('ui')['cancel_button'] ?? 'Cancel purchase');
    $form['actions']['submit-cancel']['#submit'] = ['commerce_cart_skip_cancel'];

    $form['actions']['submit-cancel']['#limit_validation_errors'] = [['edit_quantity']];
  }

  if (Drupal::moduleHandler()->moduleExists('commerce_cart_webform')) {
    commerce_cart_webform_remove_extended_fields($form);
  }

  unset($form['actions']['submit']);
}

function commerce_cart_skip_set_form_submit(&$form, $form_state, $function_name) {
  foreach (array_keys($form['actions']) as $action) {
    if ($action != 'preview' && isset($form['actions'][$action]['#type']) && $form['actions'][$action]['#type'] === 'submit') {
      if (Drupal::moduleHandler()
          ->moduleExists('commerce_cart_webform') && commerce_cart_webform_has_extended_form($form)) {
        // We tell the other module to commerce_cart_skip_submit after it does its thing.
        // There may be a more elegant way to do this.
        $form_state->set('commerce_cart_skip_submit', TRUE);
      }
      else {
        $form['actions'][$action]['#submit'] = [$function_name];
      }
    }
  }
}

function commerce_cart_skip_form_alter_add_to_cart_buy($rule, &$form, FormStateInterface $form_state) {
  // Don't do it if another module has hidden the submit
  if ($form['actions']['submit']['#type'] == 'hidden') {
    return;
  }

  $form['actions']['submit']['#value'] = t($rule->get('ui')['button_buy']);
  unset($form['quantity']);

  $showTerms = !isset($form['commerce_stock_notifications']);

  if ($showTerms && isset($rule->get('ui')['terms_text'])) {
    if (isset($rule->get('ui')['terms_link'])) {
      $form['skip_terms'] = [
        '#weight' => 45,
        '#markup' => '<a  class="terms" href="' . $rule->get('ui')['terms_link'] . '" target="_blank">' . t($rule->get('ui')['terms_text']) . '</a>',
      ];
    }
    else {
      $form['skip_terms'] = [
        '#weight' => 45,
        '#markup' => '<p  class="terms">' . $rule->get('ui')['terms_text'] . '</p>',
      ];
    }
  }

  $form_state->set('skip_rule', $rule);

  commerce_cart_skip_set_form_submit($form, $form_state, 'commerce_cart_skip_submit');
}

function commerce_cart_skip_get_variation($form, FormStateInterface $form_state) {
  $form_data = $form_state->getStorage();

  if (!empty($form_data['selected_variation'])) {
    return ProductVariation::load($form_data['selected_variation']);
  }
  else {
    return $form_state->getFormObject()->getEntity()->getPurchasedEntity();
  }
  return NULL;
}

function commerce_cart_skip_cancel(array $form, FormStateInterface $form_state) {
  $rule = $form_state->get('skip_rule');
  $selectedVariation = commerce_cart_skip_get_variation($form, $form_state);
  $order = commerce_cart_skip_get_order($form, $form_state);
  if ($order->getState()->isTransitionAllowed('cancel')) {
    $order->getState()->applyTransitionById('cancel');
    $order->save();
    Drupal::messenger()->addMessage(t("Order cancelled."));
  }
  else {
    Drupal::messenger()
      ->addMessage(t("Error, cannot cancel. Contact the site administrator."));
    return;
  }
}

function commerce_cart_skip_submit(array &$form, FormStateInterface $form_state) {
  $rule = $form_state->get('skip_rule');
  $selectedVariation = commerce_cart_skip_get_variation($form, $form_state);
  if (!$selectedVariation) {
    return;
  }

  $account = User::load(Drupal::currentUser()->id());

  $order_item = commerce_cart_skip_create_order_get_item($rule, $selectedVariation, $account);

  // Pass order item to form element for use by other module.
  $form['order_item'] = $order_item;

  $order = $order_item->getOrder();

  if ($order_item && $order) {
    if ($rule->get('ui')['success_result'] == 'message' && isset($rule->get('ui')['message_bought'])) {
      // Show same page
      Drupal::messenger()->addMessage(t($rule->get('ui')['message_bought']));
      return;
    }
    else {
      // Redirect to confirmation page
      $destination = '/product/purchased/' . $rule->id() . '/' . $order->id();
      Drupal::service('request_stack')
        ->getCurrentRequest()->query->set('destination', $destination);
      return new RedirectResponse($destination);
    }
  }
  else {
    Drupal::messenger()
      ->addMessage($rule->get('ui')['message_error'] ?? 'Could not buy.');
  }
  return;
}

/**
 * @param $rule
 * @param \Drupal\commerce_product\Entity\ProductVariation $productVariation
 * @param $account
 * @param $returnOrderItem
 *
 * @return \Drupal\commerce_order\Entity\OrderItem|\Drupal\Core\Entity\ContentEntityBase|\Drupal\Core\Entity\EntityBase|\Drupal\Core\Entity\EntityInterface|false
 * @throws \Drupal\Core\Entity\EntityStorageException
 */
function commerce_cart_skip_create_order_get_item($rule, ProductVariation $productVariation, $account) {
  if (!commerce_cart_skip_can_skip($rule, $productVariation, $account)) {
    return FALSE;
  }

  // Create order item for this variation
  $orderItem = OrderItem::create([
    'type' => $rule->get('order_values')['order_item_type'] ?? 'default',
    'quantity' => $rule->get('order_values')['quantity'] ?? 1,
    'unit_price' => $rule->get('order_values')['price'] ?? new Price('0.00', 'GBP'),
    'purchased_entity' => $productVariation,
  ]);
  $orderItem->save();

  // Create order for user
  $order = Order::create([
    'type' => $rule->get('order_values')['order_type'] ?? 'default',
    'state' => 'draft',
    'mail' => $account->getEmail(),
    'uid' => $account->id(),
    'store_id' => Drupal::service('commerce_store.current_store')
      ->getStore()
      ->id(),
    'order_items' => [$orderItem],
    'created' => Drupal::time()->getCurrentTime(),
    'billing_profile' => commerce_cart_skip_get_billing_profile($account),
  ]);
  $order->save();

  if ($order->getState()->isTransitionAllowed('place')) {
    $order->getState()->applyTransitionById('place');
    $order->save();
  }

  if ($order->getState()->isTransitionAllowed('completed')) {
    $order->getState()->applyTransitionById('completed');
    $order->save();
  }

  if ($order) {
    $orderItem->order_id->entity = $order;
    $orderItem->save();
  }

  return $orderItem;
}

function commerce_cart_skip_get_billing_profile($account) {
  $profile = Drupal::entityTypeManager()
    ->getStorage('profile')
    ->loadByUser($account, 'customer');

  if (!$profile) {
    $store = Drupal::service('commerce_store.current_store')->getStore();
    /** @var \Drupal\profile\Entity\ProfileInterface $profile */
    $profile = Profile::create([
      'type' => 'customer',
      'uid' => $account->id(),
      'address' => $store->getAddress(),
    ]);
    $profile->save();
  }

  return $profile;
}

function commerce_cart_skip_user_has_purchased_variation($account, ProductVariation $productVariation, $returnIds = FALSE) {
  $query = Drupal::database()->select('commerce_order_item', 'i');
  $query->join('commerce_order', 'o', 'i.order_id = o.order_id');
  $query->fields('i', ['order_item_id'])
    ->condition('i.purchased_entity', $productVariation->id(), '=')
    ->condition('o.uid', $account->id(), '=')
    ->condition('o.state', 'completed')
    ->condition('i.quantity', 0, ">")
    ->distinct();
  $ids = $query->execute()->fetchCol();
  if ($returnIds) {
    return $ids;
  }
  else {
    return count($ids) > 0;
  }
}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc