Jake Vanderwerf
2025-11-10 e9967fa22781d922ba4eb8fb44fe72d200ac4b14
inc/managers/OperationQueue.php
@@ -3,6 +3,7 @@
use JVBase\managers\CacheManager;
use Exception;
use JVBase\utility\Features;
use WP_Error;
use WP_REST_Response;
use WP_REST_Request;
@@ -79,7 +80,7 @@
    {
      global $wpdb;
      $this->wpdb = $wpdb;
      $this->cache = new CacheManager('queue');
      $this->cache = CacheManager::for('queue', DAY_IN_SECONDS);
        add_action('jvb_process_queue', [ $this, 'checkQueue' ]);
      add_action('jvb_queue_maintenance', [$this, 'hourlyMaintenance']);
        add_action('jvbEmailDailyMetricsReport', [$this, 'emailDailyMetricsReport']);
@@ -579,7 +580,7 @@
         $this->updateLastModified($user_id);
         $this->invalidateQueueCache();
         $this->cache->invalidate(self::CACHE_USER_QUEUE_PREFIX . $user_id);
         $this->cache->delete(self::CACHE_USER_QUEUE_PREFIX . $user_id);
         $this->runQueueOnShutdown();
         return [
@@ -598,12 +599,20 @@
   }
   protected function updateLastModified(int $user_id) {
      JVB()->routes('queue')->updateUserQueueTimestamp($user_id);
      if (Features::forSite()->has('dashboard')) {
         JVB()->routes('queue')->updateUserQueueTimestamp($user_id);
      }
   }
   protected function deepMerge(array $existing, array $new): array
   {
      $merged = $existing;
      if (!$this->isAssociativeArray($existing) && !$this->isAssociativeArray($new)) {
         error_log('It is an associative array!');
         return array_merge($existing, $new);
      }
      error_log('Not an associative array... moving on!');
      foreach ($new as $key => $newValue) {
         if (!array_key_exists($key, $existing)) {
            $merged[$key] = $newValue;
@@ -614,8 +623,15 @@
                  // Recursive merge going deeper, if any of them are associative arrays
                  $merged[$key] = $this->deepMerge($existingValue, $newValue);
               } else {
                  // Unique merge if indexed arrays
                  $merged[$key] = array_unique(array_merge($existingValue, $newValue), SORT_REGULAR);
                  $containsComplex = $this->containsComplexData($existingValue) || $this->containsComplexData($newValue);
                  if ($containsComplex) {
                     // Just merge and re-index - preserves all items from chunks
                     $merged[$key] = array_values(array_merge($existingValue, $newValue));
                  } else {
                     // Simple scalar arrays - use unique merge
                     $merged[$key] = array_unique(array_merge($existingValue, $newValue), SORT_REGULAR);
                  }
               }
            } elseif (is_array($existingValue) && !is_array($newValue)) {
               // The existing value is an array, but the new one isn't
@@ -663,6 +679,21 @@
      return array_keys($arr) !== range(0, count($arr) - 1);
   }
   /**
    * Check if an array contains complex data (arrays or objects)
    * @param array $arr
    * @return bool
    */
   protected function containsComplexData(array $arr): bool
   {
      foreach ($arr as $item) {
         if (is_array($item) || is_object($item)) {
            return true;
         }
      }
      return false;
   }
   protected function getEarliestScheduledTime(string $existing, string $new): string
   {
      $existing_time = strtotime($existing);
@@ -786,8 +817,8 @@
            $this->processOperation($operation);
            // Invalidate operation cache after processing
            $this->cache->invalidate(self::CACHE_OPERATION_PREFIX . $operation->id);
            $this->cache->invalidate(self::CACHE_USER_QUEUE_PREFIX . $operation->user_id);
            $this->cache->delete(self::CACHE_OPERATION_PREFIX . $operation->id);
            $this->cache->delete(self::CACHE_USER_QUEUE_PREFIX . $operation->user_id);
         }
         // Batch invalidate caches at the end
@@ -997,13 +1028,12 @@
      $keys = $cacheKeys[$scope] ?? $cacheKeys['all'];
      foreach ($keys as $key) {
         $this->cache->invalidate($key);
         $this->cache->delete($key);
      }
      if ($scope === 'all') {
         // Clear entire group for complete refresh
         $this->cache->invalidateGroup($this->cacheGroup);
         jvbUpdateCacheTimestamp('queue');
         $this->cache->invalidate();
         delete_transient('jvb_queue_status_counts');
      }
   }
@@ -1264,8 +1294,11 @@
               $filterResult['result'] = [$filterResult['result']];
            }
            // Store the result data
            error_log('Merging Old Result: '. print_r($oldResult, true));
            error_log('With Newer Result: '. print_r($filterResult['result'], true));
            $resultToStore = $this->deepMerge($oldResult, $filterResult['result']);
            error_log('Merged Result: '.print_r($resultToStore, true));
            $resultToStore['processed_at'] = current_time('mysql');
@@ -1375,7 +1408,7 @@
            }
         }
         // Clear operation cache after any update
         $this->cache->invalidate(self::CACHE_OPERATION_PREFIX . $operation->id);
         $this->cache->delete(self::CACHE_OPERATION_PREFIX . $operation->id);
         $this->updateLastModified($operation->user_id);
         return $filterResult;