Skip to content
Snippets Groups Projects

#3216713:Add formatter and static caching

4 unresolved threads

Closes #3216713

Merge request reports

Loading
Loading

Activity

Filter activity
  • Approvals
  • Assignees & reviewers
  • Comments (from bots)
  • Comments (from users)
  • Commits & branches
  • Edits
  • Labels
  • Lock status
  • Mentions
  • Merge request status
  • Tracking
155 155 return $fields;
156 156 }
157 157 }
158
159 /**
160 * Implements hook_entity_load().
161 */
162 function commerce_promotion_entity_load(array $entities, $entity_type_id) {
  • Jonathan Sacksick
    Jonathan Sacksick @jsacksick started a thread on commit 6a404c9b
  • 155 155 return $fields;
    156 156 }
    157 157 }
    158
    159 /**
    160 * Implements hook_entity_load().
    161 */
    162 function commerce_promotion_entity_load(array $entities, $entity_type_id) {
    163 // Add static caching for usage promotions and coupons.
    164 $applicable_entity_type = in_array($entity_type_id, ['commerce_promotion', 'commerce_promotion_coupon']);
    165 if ($applicable_entity_type) {
    166 $is_promotion = $entity_type_id == 'commerce_promotion';
    167 $cache_name = $is_promotion ? 'PromotionUsage' : 'CouponUsage';
    168 $usage_cache = &drupal_static(__FUNCTION__ . ":{$cache_name}", []);
    • That isn't what I meant by static caching.

      The static caching needs to happen in the PromotionUsage service.

      Using two properties on the service.

      $couponUsage and $promotionUsage;

      The usage should be cleared on register().

      $couponUsage and $promotionUsage should be two arrays keyed. $couponUsage needs to be keyed by coupon id and promotion usage by promotion ID.

    • Please register or sign in to reply
  • Jonathan Sacksick
    Jonathan Sacksick @jsacksick started a thread on commit 6a404c9b
  • 163 // Add static caching for usage promotions and coupons.
    164 $applicable_entity_type = in_array($entity_type_id, ['commerce_promotion', 'commerce_promotion_coupon']);
    165 if ($applicable_entity_type) {
    166 $is_promotion = $entity_type_id == 'commerce_promotion';
    167 $cache_name = $is_promotion ? 'PromotionUsage' : 'CouponUsage';
    168 $usage_cache = &drupal_static(__FUNCTION__ . ":{$cache_name}", []);
    169
    170 if (empty($usage_cache)) {
    171 $usage_service = \Drupal::service('commerce_promotion.usage');
    172 $usage_cache = $is_promotion ?
    173 $usage_service->loadMultiple($entities) :
    174 $usage_service->loadMultipleByCoupon($entities);
    175 }
    176
    177 foreach ($entities as $entity) {
    178 $entity->usage = (int) $usage_cache[$entity->id()];
  • Jonathan Sacksick
    Jonathan Sacksick @jsacksick started a thread on commit 6a404c9b
  • 17 * },
    18 * )
    19 */
    20 class UsageLimitFormatter extends FormatterBase {
    21
    22 /**
    23 * {@inheritdoc}
    24 */
    25 public function viewElements(FieldItemListInterface $items, $langcode) {
    26 $elements = [];
    27 $field_name = $items->getName();
    28 $entity = $items->getEntity();
    29
    30 // Get usage for promotions and coupons from the
    31 //static cache populated in hook_entity_load().
    32 $current_usage = $entity->usage;
  • added 1 commit

    Compare with previous version

  • 39 53 'mail' => $order->getEmail(),
    40 54 ])
    41 55 ->execute();
    56
    57 // Clear static cache for usage count of promotion/coupon.
    58 $this->promotionUsage[$promotion->id()] = 0;
  • 94 114 }
    95 $promotion_ids = EntityHelper::extractIds($promotions);
    96 $query = $this->connection->select('commerce_promotion_usage', 'cpu');
    97 $query->addField('cpu', 'promotion_id');
    98 $query->addExpression('COUNT(promotion_id)', 'count');
    99 $query->condition('promotion_id', $promotion_ids, 'IN');
    100 if (!empty($mail)) {
    101 $query->condition('mail', $mail);
    102 }
    103 $query->groupBy('promotion_id');
    104 $result = $query->execute()->fetchAllAssoc('promotion_id', \PDO::FETCH_ASSOC);
    105 // Ensure that each promotion ID gets a count, even if it's not present
    106 // in the query due to non-existent usage.
    115
    116 // Add static caching for usage promotions.
    117 $this->promotionUsage = &drupal_static(__METHOD__, []);
    • The static cache is $this->promotionUsage, there's no need to call &drupal_static() inside a class.

      That is how I think loadMultiple() should look like:

        public function loadMultiple(array $promotions, $mail = NULL) {
          if (empty($promotions)) {
            return [];
          }
          $promotion_ids = EntityHelper::extractIds($promotions);
          $usage_to_load = $promotion_ids;
      
          // When not specifying an email, filter out the promotion IDS for which we
          // already fetched the usage.
          if (!$mail) {
            $usage_to_load = array_diff_key($promotion_ids, $this->promotionUsage);
          }
      
          if ($usage_to_load) {
            $query = $this->connection->select('commerce_promotion_usage', 'cpu');
            $query->addField('cpu', 'promotion_id');
            $query->addExpression('COUNT(promotion_id)', 'count');
            $query->condition('promotion_id', $usage_to_load, 'IN');
            if (!empty($mail)) {
              $query->condition('mail', $mail);
            }
            $query->groupBy('promotion_id');
            $this->promotionUsage += $query->execute()->fetchAllAssoc('promotion_id', \PDO::FETCH_ASSOC);
          }
          // Ensure that each promotion ID gets a count, even if it's not present
          // in the query due to non-existent usage.
          $counts = [];
          foreach ($promotion_ids as $promotion_id) {
            $counts[$promotion_id] = 0;
            if (isset($this->promotionUsage[$promotion_id])) {
              $counts[$promotion_id] = $this->promotionUsage[$promotion_id]['count'];
            }
          }
      
          return $counts;
        }
      

      This will get the usage from the static cache if present, but only when the email is not specified.

      Static cache for when the email is specified is probably unnecessary as this is done only once per request.

    • changed this line in version 3 of the diff

    • Please register or sign in to reply
  • 47 * @param array $third_party_settings
    48 * Any third party settings.
    49 * @param \Drupal\commerce_promotion\PromotionUsageInterface $usage
    50 * The usage.
    51 */
    52 public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, PromotionUsageInterface $usage) {
    53 parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings);
    54
    55 $this->usage = $usage;
    56 }
    57
    58 /**
    59 * {@inheritdoc}
    60 */
    61 public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    62 return new static($plugin_id, $plugin_definition, $configuration['field_definition'], $configuration['settings'], $configuration['label'], $configuration['view_mode'], $configuration['third_party_settings'], $container->get('commerce_promotion.usage'));
  • 124 161 }
    125 $coupon_ids = EntityHelper::extractIds($coupons);
    126 $query = $this->connection->select('commerce_promotion_usage', 'cpu');
    127 $query->addField('cpu', 'coupon_id');
    128 $query->addExpression('COUNT(coupon_id)', 'count');
    129 $query->condition('coupon_id', $coupon_ids, 'IN');
    130 if (!empty($mail)) {
    131 $query->condition('mail', $mail);
    132 }
    133 $query->groupBy('coupon_id');
    134 $result = $query->execute()->fetchAllAssoc('coupon_id', \PDO::FETCH_ASSOC);
    135 // Ensure that each coupon ID gets a count, even if it's not present
    136 // in the query due to non-existent usage.
    162
    163 // Add static caching for usage coupons.
    164 $this->couponUsage = &drupal_static(__METHOD__, []);
  • added 1 commit

    Compare with previous version

  • added 1 commit

    Compare with previous version

  • Please register or sign in to reply
    Loading