View source
<?php
namespace Drupal\commerce_promotion;
use Drupal\commerce\CommerceContentEntityStorage;
use Drupal\commerce_order\Entity\OrderInterface;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Cache\MemoryCache\MemoryCacheInterface;
use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
class PromotionStorage extends CommerceContentEntityStorage implements PromotionStorageInterface {
protected $usage;
public function __construct(EntityTypeInterface $entity_type, Connection $database, EntityFieldManagerInterface $entity_field_manager, CacheBackendInterface $cache, LanguageManagerInterface $language_manager, MemoryCacheInterface $memory_cache, EntityTypeBundleInfoInterface $entity_type_bundle_info, EntityTypeManagerInterface $entity_type_manager, EventDispatcherInterface $event_dispatcher, PromotionUsageInterface $usage) {
parent::__construct($entity_type, $database, $entity_field_manager, $cache, $language_manager, $memory_cache, $entity_type_bundle_info, $entity_type_manager, $event_dispatcher);
$this->usage = $usage;
}
public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
return new static($entity_type, $container
->get('database'), $container
->get('entity_field.manager'), $container
->get('cache.entity'), $container
->get('language_manager'), $container
->get('entity.memory_cache'), $container
->get('entity_type.bundle.info'), $container
->get('entity_type.manager'), $container
->get('event_dispatcher'), $container
->get('commerce_promotion.usage'));
}
public function loadAvailable(OrderInterface $order, array $offer_ids = []) {
$date = $order
->getCalculationDate()
->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT);
$query = $this
->getQuery();
$or_condition = $query
->orConditionGroup()
->condition('end_date', $date, '>')
->notExists('end_date');
$query
->condition('stores', [
$order
->getStoreId(),
], 'IN')
->condition('order_types', [
$order
->bundle(),
], 'IN')
->condition('start_date', $date, '<=')
->condition('status', TRUE)
->condition($or_condition)
->accessCheck(FALSE);
if ($offer_ids) {
$query
->condition('offer.target_plugin_id', $offer_ids, 'IN');
}
$query
->notExists('coupons');
$result = $query
->execute();
if (empty($result)) {
return [];
}
$promotions = $this
->loadMultiple($result);
$promotions_with_usage_limits = array_filter($promotions, function ($promotion) {
return !empty($promotion
->getUsageLimit());
});
$usages = $this->usage
->loadMultiple($promotions_with_usage_limits);
foreach ($promotions_with_usage_limits as $promotion_id => $promotion) {
if ($promotion
->getUsageLimit() <= $usages[$promotion_id]) {
unset($promotions[$promotion_id]);
}
}
$promotions_with_customer_usage_limits = array_filter($promotions, function ($promotion) {
return !empty($promotion
->getCustomerUsageLimit());
});
$email = $order
->getEmail();
if (!$email) {
foreach ($promotions_with_customer_usage_limits as $promotion_id => $promotion) {
unset($promotions[$promotion_id]);
}
}
else {
$customer_usages = $this->usage
->loadMultiple($promotions_with_customer_usage_limits, $email);
foreach ($promotions_with_customer_usage_limits as $promotion_id => $promotion) {
if ($promotion
->getCustomerUsageLimit() <= $customer_usages[$promotion_id]) {
unset($promotions[$promotion_id]);
}
}
}
uasort($promotions, [
$this->entityType
->getClass(),
'sort',
]);
return $promotions;
}
}