| | |
| | | |
| | | use JVBase\managers\CacheManager; |
| | | use Exception; |
| | | use JVBase\utility\Features; |
| | | use WP_Error; |
| | | use WP_REST_Response; |
| | | use WP_REST_Request; |
| | |
| | | { |
| | | 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']); |
| | |
| | | |
| | | $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 [ |
| | |
| | | } |
| | | |
| | | 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; |
| | |
| | | // 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 |
| | |
| | | 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); |
| | |
| | | $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 |
| | |
| | | $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'); |
| | | } |
| | | } |
| | |
| | | $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'); |
| | | |
| | |
| | | } |
| | | } |
| | | // 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; |
| | | |