From a9654f00c8fbc9934289d761843ddd071025013f Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Fri, 28 Aug 2026 17:20:28 +0000
Subject: [PATCH] =PHPStorm Code Inspection: fixed class reference errors (from getting rid of JVB() and replacing with direct class::getInstance; as well as general code sniffing, etc

---
 inc/managers/queue/executors/UploadExecutor.php |  307 ++++++++++++++++++++++++--------------------------
 1 files changed, 149 insertions(+), 158 deletions(-)

diff --git a/inc/managers/queue/executors/UploadExecutor.php b/inc/managers/queue/executors/UploadExecutor.php
index cc828d5..138d022 100644
--- a/inc/managers/queue/executors/UploadExecutor.php
+++ b/inc/managers/queue/executors/UploadExecutor.php
@@ -1,12 +1,14 @@
 <?php
 namespace JVBase\managers\queue\executors;
 
-use JVBase\managers\queue\{Executor, Operation, Progress, Result};
+use JVBase\managers\queue\{Executor, Operation, Progress, Queue, Result};
 use JVBase\managers\Cache;
+use JVBase\managers\Errors;
 use JVBase\managers\UploadManager;
 use JVBase\meta\Meta;
 use Exception;
-use JVBase\utility\Features;
+use JVBase\registrar\Registrar;
+use WP_Error;
 
 if (!defined('ABSPATH')) {
 	exit;
@@ -29,10 +31,16 @@
 		'process_upload_groups'
 	];
 
+	/**
+	 * @param Operation $operation
+	 * @param Progress $progress
+	 * @return Result
+	 * @throws Exception
+	 */
 	public function execute(Operation $operation, Progress $progress): Result
 	{
 		if (!in_array($operation->type, self::HANDLED_TYPES)) {
-			throw new Exception("UploadExecutor cannot handle type: {$operation->type}");
+			throw new Exception("UploadExecutor cannot handle type: $operation->type");
 		}
 
 		try {
@@ -46,11 +54,11 @@
 				'temporary_cleanup'       => $this->processTemporaryCleanup($operation, $data, $progress),
 				'attach_upload_to_content'=> $this->processAttachToContent($operation, $data, $progress),
 				'process_upload_groups'   => $this->processUploadGroups($operation, $data, $progress),
-				default                   => throw new Exception("Unknown type: {$operation->type}")
+				default                   => throw new Exception("Unknown type: $operation->type")
 			};
 
 		} catch (Exception $e) {
-			JVB()->error()->log(
+			Errors::getInstance()->log(
 				'[UploadExecutor]:execute',
 				$e->getMessage(),
 				[
@@ -72,74 +80,32 @@
 	 */
 	private function processFileUpload(Operation $operation, array $data, string $fileType, Progress $progress): Result
 	{
-		$uploader = new UploadManager();
-		$processedResults = [];
+		$uploader = UploadManager::getInstance();
 		$errors = [];
 		$uploadIds = [];
 
 		$securedFiles = $data['secured_files'] ?? [];
+		$args = $data;
+		unset($args['secured_files']);
 
-		// Phase 1: File I/O — no DB, no transactions
 		$prepared = [];
 		foreach ($securedFiles as $securedFile) {
 			$uploadIds[] = $securedFile['upload_id'];
 			try {
-				$prepared[$securedFile['upload_id']] = $uploader->prepareFile(
+				$prepared[$securedFile['upload_id']] = $uploader->processUpload(
 					$securedFile['temp_path'],
-					[
-						'file_type'     => $fileType,
-						'user_id'       => $operation->userId,
-						'post_id'       => (int)($data['post_id'] ?? 0),
-						'term_id'       => (int)($data['term_id'] ?? 0),
-						'original_name' => $securedFile['original_name'],
-						'mime_type'     => $securedFile['mime_type'],
-						'content'       => $data['content'] ?? '',
-					]
+					$args
 				);
+				$progress->advance();
 			} catch (Exception $e) {
 				$progress->failItem($securedFile['upload_id'], $e->getMessage());
 				$errors[] = $e->getMessage();
 			}
 		}
 
-		// Phase 2: DB registration — quick per-file writes
-		foreach ($prepared as $uploadId => $fileInfo) {
-			try {
-				$result = $uploader->registerFile($fileInfo);
 
-				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';
-		if (count($processedResults) > 0 && !empty($errors)) {
+		$outcome = count($prepared) > 0 ? 'success' : 'failed';
+		if (count($prepared) > 0 && !empty($errors)) {
 			$outcome = 'partial';
 		}
 
@@ -147,8 +113,8 @@
 			outcome: $outcome,
 			result: [
 				'upload_ids'      => $uploadIds,
-				'uploads'         => $processedResults,
-				'processed_count' => count($processedResults),
+				'uploads'         => $prepared,
+				'processed_count' => count($prepared),
 				'total_count'     => count($uploadIds),
 				'errors'          => $errors,
 			]
@@ -156,20 +122,12 @@
 	}
 
 	/**
-	 * 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
+	 * @param Operation $operation
+	 * @param array $data
+	 * @param Progress $progress
+	 * @return Result
+	 * @throws Exception
 	 */
 	private function processAttachToContent(Operation $operation, array $data, Progress $progress): Result
 	{
@@ -179,9 +137,9 @@
 			throw new Exception('No upload operation ID provided');
 		}
 
-		$uploadOp = JVB()->queue()->get($uploadOpId);
+		$uploadOp = Queue::getInstance()->get($uploadOpId);
 		if (!$uploadOp || !in_array($uploadOp->outcome, ['success', 'partial'])) {
-			throw new Exception("Upload operation {$uploadOpId} not completed successfully");
+			throw new Exception("Upload operation $uploadOpId not completed successfully");
 		}
 
 		$uploadResults = $uploadOp->result['uploads'] ?? [];
@@ -192,7 +150,7 @@
 		// Resolve post_id from content_update dependency for new posts
 		if (empty($data['post_id']) || str_starts_with((string)($data['item_id'] ?? ''), 'new')) {
 			foreach ($operation->dependencies as $depId) {
-				$dep = JVB()->queue()->get($depId);
+				$dep = Queue::getInstance()->get($depId);
 				if ($dep && $dep->type === 'content_update' && !empty($dep->result['new_posts'])) {
 					$itemId = $data['item_id'] ?? null;
 					if ($itemId && isset($dep->result['new_posts'][$itemId])) {
@@ -208,10 +166,39 @@
 		}
 
 		if (!empty($data['field_name'])) {
-			$this->saveToMeta($data, $uploadResults);
+			if ($data['field_name'] === 'timeline_gallery') {
+				$registrar = Registrar::getInstance($data['content']);
+				if ($registrar) {
+					$meta = match ($registrar->getType()) {
+						'post' => Meta::forPost($data['item_id']),
+						'term' => Meta::forTerm($data['item_id']),
+						'user' => Meta::forUser($data['item_id']),
+						default => false,
+					};
+
+					if ($meta) {
+						$title = $meta->get('post_title');
+						$current = $meta->get('number');
+						$i = empty($current) ? 1 : $current + 1;
+						foreach ($data['upload_ids'] as $uploadID) {
+							if (!array_key_exists($uploadID, $uploadResults)) {
+								continue;
+							}
+							$imgID = $uploadResults[$uploadID]['attachment_id'] ?? false;
+							if (!$imgID) {
+								continue;
+							}
+							$this->createTimelinePoint($imgID, $data['item_id'], $data['user'], $data['content'], $title, $i);
+							$i++;
+						}
+					}
+				}
+			} else {
+				$this->saveToMeta($data, $uploadResults);
+			}
 		}
 
-		$progress->advance(1);
+		$progress->advance();
 
 		return new Result(
 			outcome: 'success',
@@ -219,6 +206,25 @@
 		);
 	}
 
+		protected function createTimelinePoint(int $imgID, int $parentID, int $user, string $postType, string $baseTitle, int $index):int|WP_Error
+		{
+			$title = $baseTitle.' - Treatment #'.$index;
+			$args = [
+				'post_type'		=> jvbCheckBase($postType),
+				'post_author'	=> $user,
+				'post_status'	=> 'draft',
+				'post_parent'	=> $parentID,
+				'post_title'	=> $title,
+				'post_name'		=> sanitize_title($title)
+			];
+
+			$child = wp_insert_post($args);
+			if ($child && !is_wp_error($child)) {
+				set_post_thumbnail($child, $imgID);
+			}
+			return $child;
+		}
+
 	/**
 	 * Process metadata updates for attachments
 	 */
@@ -231,13 +237,14 @@
 		error_log('Processing Meta Update with data: '.print_r($data, true));
 		foreach ($data as $uploadId => $info) {
 			if (!is_array($info)) {
+				error_log('Not an array for processing meta update: '.print_r($info, true));
 				continue;
 			}
 			$success = true;
 			try {
 				if (array_key_exists('depends_on', $info)) {
 					// Get the dependency operation to find attachment ID
-					$depOp = JVB()->queue()->get($info['depends_on']);
+					$depOp = Queue::getInstance()->get($info['depends_on']);
 					if (!$depOp || !$depOp->result) {
 						$errors[] = "Dependency {$info['depends_on']} not found or has no result";
 						continue;
@@ -255,31 +262,20 @@
 					$errors[] = "No attachment found for: ".print_r($info, true);
 					continue;
 				}
-
-
+				$postID = wp_get_post_parent_id($attachmentId);
+				if ($postID && !in_array($postID, $postsAttachedTo)){
+					Cache::clearPost($postID);
+				}
 
 				$this->applyMeta($attachmentId, $info);
 				$updatedCount++;
-				$progress->advance(1);
+				$progress->advance();
 
 			} 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';
@@ -297,11 +293,14 @@
 	}
 
 	/**
-	 * Cleanup temporary upload files
+	 * @param Operation $operation
+	 * @param array $data
+	 * @param Progress $progress
+	 * @return Result
 	 */
 	private function processTemporaryCleanup(Operation $operation, array $data, Progress $progress): Result
 	{
-		$uploader = new UploadManager();
+		$uploader = UploadManager::getInstance();
 
 		// Cleanup secured files
 		if (!empty($data['files'])) {
@@ -309,7 +308,7 @@
 				if (!empty($file['temp_path']) && file_exists($file['temp_path'])) {
 					@unlink($file['temp_path']);
 				}
-				$progress->advance(1);
+				$progress->advance();
 			}
 		}
 
@@ -345,7 +344,7 @@
 		$uploads = [];
 		$uploadIds = [];
 		foreach ($dependencies as $dependency) {
-			$res = JVB()->queue()->getOperationValue($dependency, 'result');
+			$res = Queue::getInstance()->getOperationValue($dependency, 'result');
 			if (empty($res)) {
 				continue;
 			}
@@ -384,7 +383,8 @@
 		}
 
 		$content = jvbCheckBase($data['content']);
-		if (Features::forContent($data['content'])->has('is_timeline')) {
+		$registrar = Registrar::getInstance($data['content']);
+		if ($registrar && $registrar->hasFeature('is_timeline')) {
 			return $this->processTimelineUploads($operation, $data, $progress, $all_uploads);
 		}
 
@@ -412,7 +412,7 @@
 					}
 
 					$usedUploads = array_merge($usedUploads, $created['usedUploads']);
-					$progress->advance(1);
+					$progress->advance();
 				}
 			} catch (Exception $e) {
 				$errors[] = $e->getMessage();
@@ -438,14 +438,11 @@
 
 	protected function createPostFromGroup(array $post, int $index, string $content, array $uploads, Operation $op):array|false
 	{
-		$config = JVB_CONTENT[jvbNoBase($content)]??false;
-		if (!$config) {
-			throw new Exception('No config found for content: '.$content.'.');
-		}
+		$registrar = Registrar::getInstance($content);
 
 		$post_title = array_key_exists('post_title', $post['fields'])
 			? sanitize_text_field($post['fields']['post_title'])
-			: 'New '. $config['singular'].' '.($index + 1);
+			: ($registrar ? 'New '. $registrar->getSingular().' '.($index + 1) : 'New Item '.($index + 1));
 
 		$post_excerpt = array_key_exists('post_excerpt', $post['fields'])
 			? sanitize_textarea_field($post['fields']['post_excerpt'])
@@ -489,7 +486,7 @@
 
 		if (!empty($gallery)) {
 			$meta = Meta::forPost($ID);
-			$fields = jvbGetFields($content, 'post');
+			$fields = Registrar::getFieldsFor($content);
 			//add images to first found gallery field
 			$found = false;
 			foreach ($fields as $name =>$config) {
@@ -503,7 +500,6 @@
 				error_log('Could not find a gallery upload field for post '.$ID);
 			}
 
-			$meta->save();
 		}
 
 
@@ -521,9 +517,10 @@
 		$errors = [];
 
 		$content = jvbCheckBase($data['content']);
-		$config = Features::getConfig($content);
+		$registrar = Registrar::getInstance($data['content']);
 
-		$defaultTitle = 'New '.$config['singular']. ' ';
+
+		$defaultTitle = ($registrar) ? 'New '.$registrar->getSingular(). ' ' : 'New Item ';
 		foreach($data['posts'] as $index => $post) {
 			try {
 				$title = array_key_exists('post_title', $post['fields'])
@@ -539,7 +536,7 @@
 					'post_author'	=> $user,
 					'post_status'	=> 'draft',
 					'post_title'	=> $title,
-					'post_slug'		=> sanitize_title($title),
+					'post_name'		=> sanitize_title($title),
 					'post_excerpt'	=> $excerpt
 				];
 
@@ -560,7 +557,7 @@
 					if (array_key_exists($uploadId, $uploads)) {
 						$attachmentId = (int)$uploads[$uploadId]['attachment_id'];
 						if ($uploadId === $featured) {
-							$featuredID = $attachmentId;;
+							$featuredID = $attachmentId;
 						} else {
 							$childPosts[] = $attachmentId;
 						}
@@ -583,12 +580,10 @@
 
 					foreach($childPosts as $i => $imgID) {
 						$treatment = $i + 1;
-						$args ['post_title'] = $title.' - Treatment #'.$treatment;
-						$child = wp_insert_post($args);
-						if ($child && !is_wp_error($child)) {
-							$createdChildren = $child;
+						$child = $this->createTimelinePoint($imgID, $parent, $args['post_author'], $args['post_type'], $title, $treatment);
+						if ($child && !is_wp_error($child) && $child> 0 ) {
+							$createdChildren[] = $child;
 							$usedUploads[] = $imgID;
-							set_post_thumbnail($child, $imgID);
 						}
 					}
 				}
@@ -628,14 +623,7 @@
 	private function updateTimelineMetadata(int $parentId): void
 	{
 		// Get all child posts
-		$children = get_children([
-			'post_parent' => $parentId,
-			'post_type' => get_post_type($parentId),
-			'post_status' => ['publish', 'draft'],
-			'orderby' => 'date',
-			'order' => 'DESC',
-			'fields' => 'ids'
-		]);
+		$children = jvbTimelinePoints($parentId, get_post_type($parentId), ['any']);
 
 		// Count includes parent + children
 		$number = count($children) + 1;
@@ -649,26 +637,47 @@
 	// Helper methods
 	// ─────────────────────────────────────────────────────────────
 
+	/**
+	 * @param int $attachmentId
+	 * @param array $metadata
+	 * @return void
+	 */
 	private function applyMeta(int $attachmentId, array $metadata): void
 	{
-		if (array_key_exists('image-alt-text', $metadata)) {
-			update_post_meta($attachmentId, '_wp_attachment_image_alt', sanitize_text_field($metadata['image-alt-text']));
-		}
-
 		$postUpdates = [];
+		foreach ($metadata as $key => $value) {
+			//Remove the image_data| from the  meta's group formatting
+			$base = 'image_data|';
+			$key = str_replace($base, '', $key);
+			if ($key === 'image-alt-text') {
+				error_log('Updating Image Alt Text: '.print_r($value, true));
+				update_post_meta($attachmentId, '_wp_attachment_image_alt', sanitize_text_field($value));
+				continue;
+			}
 
-		if (array_key_exists('image-title', $metadata)) {
-			$postUpdates['post_title'] = sanitize_text_field($metadata['image-title']);
+			$k = match ($key) {
+				'image-title'	=> 'post_title',
+				'image-caption' => 'post_excerpt',
+				'image-description' => 'post_content',
+				default => false
+			};
+			if (!$k) {
+				error_log('No matching key for '.$key.' with value: '.print_r($value, true));
+				continue;
+			}
+			$v = match ($key) {
+				'image-title'	=> sanitize_text_field($value),
+				default			=> sanitize_textarea_field($value)
+			};
+			$postUpdates[$k] = $v;
+
 		}
 
-		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;
+			$postUpdates['post_type'] = 'attachment';
+
+			error_log('Updating Image post with data: '.print_r($postUpdates, true));
 			wp_update_post($postUpdates);
 		}
 	}
@@ -715,27 +724,6 @@
 			$meta->set($data['field_name'], implode(',', $allIds));
 		}
 
-		$meta->save();
-	}
-
-	private function updateFieldValue(array $data, array $results): void
-	{
-		if (empty($data['field_name'])) {
-			return;
-		}
-
-		$attachmentIds = array_column($results, 'attachment_id');
-		$meta = $this->getMetaManager($data);
-		if (!$meta) {
-			return;
-		}
-
-		$existing = $meta->get($data['field_name']);
-		$existingIds = !empty($existing) ? explode(',', $existing) : [];
-		$allIds = array_unique(array_merge($existingIds, $attachmentIds));
-
-		$meta->set($data['field_name'], implode(',', $allIds));
-		$meta->save();
 	}
 
 	private function getMetaManager(array $data): ?Meta
@@ -755,6 +743,11 @@
 		return null;
 	}
 
+	/**
+	 * @param array $data
+	 * @param array $results
+	 * @return array
+	 */
 	private function createIndividualPosts(array $data, array $results): array
 	{
 		if (empty($data['content'])) {
@@ -798,20 +791,18 @@
 		} elseif (str_starts_with($mimeType, 'video/')) {
 			$meta = Meta::forPost($postId);
 			$meta->set('video', $attachmentId);
-			$meta->save();
 		} else {
 			$meta = Meta::forPost($postId);
 			$existing = $meta->get('documents');
 			$existingIds = !empty($existing) ? explode(',', $existing) : [];
 			$existingIds[] = $attachmentId;
 			$meta->set('documents', implode(',', $existingIds));
-			$meta->save();
 		}
 	}
 
 	private function cleanupTempFiles(array $securedFiles, int $userId): void
 	{
-		$uploader = new UploadManager();
+		$uploader = UploadManager::getInstance();
 
 		foreach ($securedFiles as $secured) {
 			if (!empty($secured['temp_path']) && file_exists($secured['temp_path'])) {

--
Gitblit v1.10.0