From 27fb820ae9081fb56957cf75e79eccd8a99edd52 Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Sat, 14 Feb 2026 19:14:48 +0000
Subject: [PATCH] =minor css changes, queue merge logic restructured, and double checking changes actually changed in cRUD.js before sending to server

---
 inc/managers/queue/executors/UploadExecutor.php |  133 ++++++++++++++++++++++++++++++--------------
 1 files changed, 90 insertions(+), 43 deletions(-)

diff --git a/inc/managers/queue/executors/UploadExecutor.php b/inc/managers/queue/executors/UploadExecutor.php
index 1d42036..cc828d5 100644
--- a/inc/managers/queue/executors/UploadExecutor.php
+++ b/inc/managers/queue/executors/UploadExecutor.php
@@ -2,6 +2,7 @@
 namespace JVBase\managers\queue\executors;
 
 use JVBase\managers\queue\{Executor, Operation, Progress, Result};
+use JVBase\managers\Cache;
 use JVBase\managers\UploadManager;
 use JVBase\meta\Meta;
 use Exception;
@@ -78,10 +79,12 @@
 
 		$securedFiles = $data['secured_files'] ?? [];
 
+		// Phase 1: File I/O — no DB, no transactions
+		$prepared = [];
 		foreach ($securedFiles as $securedFile) {
 			$uploadIds[] = $securedFile['upload_id'];
 			try {
-				$result = $uploader->processUpload(
+				$prepared[$securedFile['upload_id']] = $uploader->prepareFile(
 					$securedFile['temp_path'],
 					[
 						'file_type'     => $fileType,
@@ -93,35 +96,46 @@
 						'content'       => $data['content'] ?? '',
 					]
 				);
-
-				if (is_wp_error($result)) {
-					$progress->failItem($securedFile['upload_id'], $result->get_error_message());
-					$errors[] = $result->get_error_message();
-					continue;
-				}
-
-				$processedResults[$securedFile['upload_id']] = [
-					'upload_id' => $securedFile['upload_id'],
-					'attachment_id' => $result['attachment_id'] ?? 0,
-					'url' => $result['url'] ?? '',
-					'sizes' => $result['sizes'] ?? [],
-				];
-				if (!empty($securedFile['metadata'])) {
-					$this->applyMeta($securedFile['attachment_id'], $securedFile['metadata']);
-				}
-
-				$progress->advance();
-
 			} catch (Exception $e) {
 				$progress->failItem($securedFile['upload_id'], $e->getMessage());
 				$errors[] = $e->getMessage();
 			}
 		}
 
-		// Handle destination (meta, post, post_group)
-		$this->handleUploadDestination($data, $processedResults);
+		// Phase 2: DB registration — quick per-file writes
+		foreach ($prepared as $uploadId => $fileInfo) {
+			try {
+				$result = $uploader->registerFile($fileInfo);
 
-		// Cleanup temp files
+				if (!$result['success']) {
+					$progress->failItem($uploadId, 'Registration failed');
+					$errors[] = "Failed to register {$uploadId}";
+					continue;
+				}
+
+				$processedResults[$uploadId] = [
+					'upload_id'     => $uploadId,
+					'attachment_id' => $result['attachment_id'] ?? 0,
+					'url'           => $result['url'] ?? '',
+					'sizes'         => $result['sizes'] ?? [],
+				];
+
+				// Apply frontend metadata if provided
+				$securedFile = $this->findSecuredFile($securedFiles, $uploadId);
+				if ($securedFile && !empty($securedFile['metadata'])) {
+					$this->applyMeta($result['attachment_id'], $securedFile['metadata']);
+				}
+
+				$progress->advance();
+
+			} catch (Exception $e) {
+				$progress->failItem($uploadId, $e->getMessage());
+				$errors[] = $e->getMessage();
+			}
+		}
+
+		// Destination + cleanup unchanged
+		$this->handleUploadDestination($data, $processedResults);
 		$this->cleanupTempFiles($securedFiles, $operation->userId);
 
 		$outcome = count($processedResults) > 0 ? 'success' : 'failed';
@@ -132,21 +146,35 @@
 		return new Result(
 			outcome: $outcome,
 			result: [
-				'upload_ids'	=> $uploadIds,
-				'uploads'		=> $processedResults,
-				'processed_count'=> count($processedResults),
-				'total_count'	=> count($uploadIds),
-				'errors'		=> $errors
+				'upload_ids'      => $uploadIds,
+				'uploads'         => $processedResults,
+				'processed_count' => count($processedResults),
+				'total_count'     => count($uploadIds),
+				'errors'          => $errors,
 			]
 		);
 	}
 
 	/**
+	 * Find a secured file entry by upload_id
+	 */
+	private function findSecuredFile(array $securedFiles, string $uploadId): ?array
+	{
+		foreach ($securedFiles as $file) {
+			if (($file['upload_id'] ?? null) === $uploadId) {
+				return $file;
+			}
+		}
+		return null;
+	}
+
+	/**
 	 * Attach upload results to content
 	 */
 	private function processAttachToContent(Operation $operation, array $data, Progress $progress): Result
 	{
 		$uploadOpId = $data['upload'] ?? null;
+		error_log('processing attached to content: '.print_r($data, true));
 		if (!$uploadOpId) {
 			throw new Exception('No upload operation ID provided');
 		}
@@ -199,11 +227,13 @@
 		$updatedCount = 0;
 		$errors = [];
 
+		$postsAttachedTo =[];
+		error_log('Processing Meta Update with data: '.print_r($data, true));
 		foreach ($data as $uploadId => $info) {
 			if (!is_array($info)) {
 				continue;
 			}
-
+			$success = true;
 			try {
 				if (array_key_exists('depends_on', $info)) {
 					// Get the dependency operation to find attachment ID
@@ -233,9 +263,23 @@
 				$progress->advance(1);
 
 			} catch (Exception $e) {
+				$success = false;
 				$progress->failItem($uploadId, $e->getMessage());
 				$errors[] = $e->getMessage();
 			}
+
+			if ($success) {
+				$postID = wp_get_post_parent_id($attachmentId);
+				if ($postID && !in_array($postID, $postsAttachedTo)){
+					$postsAttachedTo[] = $postID;
+				}
+			}
+
+		}
+		if (!empty ($postsAttachedTo)) {
+			foreach ($postsAttachedTo as $postId) {
+				Cache::invalidateItem('post', $postId);
+			}
 		}
 
 		$outcome = $updatedCount > 0 ? 'success' : 'failed';
@@ -449,7 +493,7 @@
 			//add images to first found gallery field
 			$found = false;
 			foreach ($fields as $name =>$config) {
-				if ($config['type'] === 'upload' && (array_key_exists('multiple', $config) && $config['multiple'] === true)) {
+				if ($config['type'] === 'gallery' || ($config['type'] === 'upload' && (array_key_exists('multiple', $config) && $config['multiple'] === true))) {
 					$found = true;
 					$meta->set($name, implode(',', $gallery));
 					break;
@@ -607,22 +651,25 @@
 
 	private function applyMeta(int $attachmentId, array $metadata): void
 	{
-		if (!empty($metadata['image-title'])) {
-			wp_update_post([
-				'ID'         => $attachmentId,
-				'post_title' => sanitize_text_field($metadata['image-title']),
-			]);
-		}
-
-		if (!empty($metadata['image-alt-text'])) {
+		if (array_key_exists('image-alt-text', $metadata)) {
 			update_post_meta($attachmentId, '_wp_attachment_image_alt', sanitize_text_field($metadata['image-alt-text']));
 		}
 
-		if (!empty($metadata['image-caption'])) {
-			wp_update_post([
-				'ID'           => $attachmentId,
-				'post_excerpt' => sanitize_textarea_field($metadata['image-caption']),
-			]);
+		$postUpdates = [];
+
+		if (array_key_exists('image-title', $metadata)) {
+			$postUpdates['post_title'] = sanitize_text_field($metadata['image-title']);
+		}
+
+		if (array_key_exists('image-caption', $metadata)) {
+			$postUpdates['post_excerpt'] = sanitize_textarea_field($metadata['image-caption']);
+		}
+		if (array_key_exists('image-description', $metadata)) {
+			$postUpdates['post_excerpt']= sanitize_textarea_field($metadata['image-caption']);
+		}
+		if (!empty($postUpdates)){
+			$postUpdates['ID'] = $attachmentId;
+			wp_update_post($postUpdates);
 		}
 	}
 

--
Gitblit v1.10.0