From b38f03c0e7218762d90fa5092696b127f24f36db Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Sun, 25 Jan 2026 07:07:26 +0000
Subject: [PATCH] =Some logical flaws in Queue.php, Queue.js, ContentExecutor.php, UploadExecutor.php - particularly with timeline ordering, frontend queue updates, etc

---
 inc/managers/queue/executors/ContentExecutor.php |   66 ++++++++++++++++++++++----------
 1 files changed, 45 insertions(+), 21 deletions(-)

diff --git a/inc/managers/queue/executors/ContentExecutor.php b/inc/managers/queue/executors/ContentExecutor.php
index cf3936d..dd4c80c 100644
--- a/inc/managers/queue/executors/ContentExecutor.php
+++ b/inc/managers/queue/executors/ContentExecutor.php
@@ -1,7 +1,6 @@
 <?php
 namespace JVBase\managers\queue\executors;
 
-use JVBase\managers\CacheManager;
 use JVBase\managers\queue\{Executor, Operation, Progress, Result};
 use JVBase\meta\MetaManager;
 use JVBase\utility\Features;
@@ -104,7 +103,11 @@
 					}
 
 					$this->savePostFields($newId, $postData);
-					$results[$id] = ['success' => true, 'new_id' => $newId];
+					$results[$id] = [
+						'success' => true,
+						'new_id' => $newId,
+						'processed_fields' => array_keys($postData)
+					];
 
 					if (Features::forContent($content)->has('is_timeline')) {
 						$this->updateTimelineLatestDate($newId);
@@ -117,6 +120,7 @@
 				// Existing post update
 				if (!$this->verifyOwnership((int)$id)) {
 					$progress->failItem($id, 'No permission to modify this post');
+					$errors[$id] = 'No permission';
 					continue;
 				}
 				// Check if this is a timeline post
@@ -156,23 +160,34 @@
 					$this->updateTimelineLatestDate($parentId);
 				}
 
-				$results[$id] = ['success' => true];
+				$results[$id] = [
+					'success' => true,
+					'processed_fields' => array_keys($postData)
+				];
 				$progress->advance(1);
 
-				// Clear caches
-				CacheManager::for($content)->clear();
-				if (jvbSiteUsesFeedBlock()) {
-					CacheManager::for('feed')->clear();
-				}
-
 			} catch (Exception $e) {
 				$progress->failItem($id, $e->getMessage());
 				$errors[$id] = $e->getMessage();
+				$results[$id] = [
+					'success' => false,
+					'error' => $e->getMessage()
+				];
 			}
 		}
 		if (!empty($updateTimelineOrder)) {
-			foreach ($updateTimelineOrder as $parentID) {
-				$this->reorderTimelineByDate($parentID);
+			$processedParents = []; // Track to avoid duplicate processing
+
+			foreach ($updateTimelineOrder as $oldParentID) {
+				if (in_array($oldParentID, $processedParents)) continue;
+
+				$actualParentId = $this->reorderTimelineByDate($oldParentID);
+				$processedParents[] = $actualParentId;
+
+				// If parent changed, mark the new parent as processed too
+				if ($actualParentId !== $oldParentID) {
+					$processedParents[] = $oldParentID;
+				}
 			}
 		}
 
@@ -193,7 +208,12 @@
 
 		return new Result(
 			outcome: $outcome,
-			result: $results
+			result: [
+				'posts' => $results,
+				'errors' => $errors,
+				'updated_count' => count(array_filter($results, fn($r) => $r['success'] ?? false)),
+				'failed_count' => count($errors)
+			]
 		);
 	}
 
@@ -247,10 +267,10 @@
 		}
 	}
 
-	private function reorderTimelineByDate(int $parentId): void
+	private function reorderTimelineByDate(int $parentId): int
 	{
 		$parent = get_post($parentId);
-		if (!$parent) return;
+		if (!$parent) return $parentId;
 
 		// Get all posts in this timeline (parent + children)
 		$children = get_posts([
@@ -269,6 +289,7 @@
 		});
 
 		$newParent = $allPosts[0];
+		$actualParentId = $newParent->ID; // Track the actual parent
 
 		// If parent changed, restructure
 		if ($newParent->ID !== $parentId) {
@@ -320,13 +341,16 @@
 
 			$timelineTerm = $this->calculateTimelineTerm($previousPost, $post);
 			if ($timelineTerm) {
-				$this->getorCreateTerm($post->ID, $timelineTerm, 'timeline');
+				$this->getOrCreateTerm($post->ID, $timelineTerm, 'timeline');
 			}
 
 			$previousPost = $post;
 		}
 
-		$this->updateTimelineLatestDate($newParent->ID);
+		// Update latest_date AFTER reordering with the actual parent
+		$this->updateTimelineLatestDate($actualParentId);
+
+		return $actualParentId; // Return the actual parent ID
 	}
 
 	private function updateTimelineLatestDate(int $parentId): void
@@ -345,6 +369,9 @@
 			'fields' => 'ids'
 		]);
 
+		// Count: parent + children
+		$number = count($children) + 1;
+
 		$allPostIds = array_merge([$parentId], $children);
 
 		// Get all timestamps
@@ -355,7 +382,8 @@
 
 		$latestTimestamp = max($timestamps);
 
-		// Store as UNIX timestamp
+		// Update both meta fields
+		update_post_meta($parentId, BASE . 'number', $number);
 		update_post_meta($parentId, BASE . 'latest_date', $latestTimestamp);
 	}
 
@@ -462,10 +490,6 @@
 			$results = $this->createFromDirect($operation, $data, $images, $progress);
 		}
 
-		// Clear caches
-		CacheManager::for($data['content'])->clear();
-		CacheManager::for('feed')->clear();
-
 		return new Result(
 			outcome: !empty($results) ? 'success' : 'failed',
 			result: $results

--
Gitblit v1.10.0