From 75a097a018a0090f5902758353c578fce4aa2a25 Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Sat, 23 May 2026 18:43:42 +0000
Subject: [PATCH] =CustomBlocks.php overhaul relatively complete. Also refactored the gallery in gallery.min.js and the jvbRenderGallery.

---
 inc/managers/UploadManager.php |  157 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 156 insertions(+), 1 deletions(-)

diff --git a/inc/managers/UploadManager.php b/inc/managers/UploadManager.php
index d1cd220..00bc05f 100644
--- a/inc/managers/UploadManager.php
+++ b/inc/managers/UploadManager.php
@@ -505,7 +505,7 @@
 
 		return apply_filters(
 			'jvb_upload_filename',
-			"{$username}-{$base_name}-{$timestamp}",
+			"{$base_name}-{$timestamp}",
 			$context
 		);
 	}
@@ -751,4 +751,159 @@
 		apply_filters('jvb_extract_video_thumbnail', null, $attachment_id, $video_path, $time);
 	}
 
+
+
+
+	/**
+	 * Phase 1: Validate and process file on disk (no DB writes)
+	 * Safe to run outside transactions — only does file I/O
+	 *
+	 * @return array Prepared file info for registerFile()
+	 */
+	public function prepareFile(string $temp_path, array $context): array
+	{
+		if (!file_exists($temp_path)) {
+			throw new Exception('Temporary file not found: ' . $temp_path);
+		}
+
+		$mime_type = mime_content_type($temp_path);
+		if (!$this->validateMimeType($temp_path, $mime_type)) {
+			throw new Exception('Invalid or potentially dangerous file type');
+		}
+
+		$file_type = $this->allowedTypes[$mime_type] ?? 'unknown';
+		if ($file_type === 'unknown') {
+			throw new Exception('Unsupported file type: ' . $mime_type);
+		}
+
+		$config  = array_merge($this->defaultConfig, $context['config'] ?? [], $context);
+		$post_id = $context['post_id'] ?? 0;
+
+		if (!empty($config['allowed_types']) && !in_array($mime_type, $config['allowed_types'])) {
+			throw new Exception('File type not allowed: ' . $mime_type);
+		}
+
+		$this->validateFileSize($temp_path, $file_type, $config);
+
+		$directory = $this->generateDirectory(
+			$file_type,
+			$config['directory_pattern'] ?? '{user_id}/{content}/{file_type}',
+			$context
+		);
+		$this->ensureDirectories($directory);
+
+		$original_name = $context['original_name'] ?? basename($temp_path);
+		$filename      = $this->generateFilename($original_name, $context);
+		$original_path = $this->storeOriginalFromTemp($temp_path, $directory, $filename);
+
+		// File-type-specific I/O (conversion, copying) — no DB
+		$final_path = match ($file_type) {
+			'image'    => $this->prepareImage($original_path, $directory, $filename, $config),
+			'video'    => $this->prepareMedia($original_path, $directory, $filename),
+			'document' => $this->prepareMedia($original_path, $directory, $filename),
+			default    => throw new Exception('Unknown file type'),
+		};
+
+		return [
+			'final_path' => $final_path,
+			'file_type'  => $file_type,
+			'filename'   => $filename,
+			'post_id'    => $post_id,
+			'config'     => $config,
+			'context'    => $context,
+		];
+	}
+
+	/**
+	 * Phase 2: Register processed file in WordPress (DB writes only)
+	 * Quick operation — individual WP functions handle their own queries
+	 *
+	 * @param array $prepared Output from prepareFile()
+	 * @return array Standard upload result
+	 */
+	public function registerFile(array $prepared): array
+	{
+		$attachment_id = $this->createAttachment(
+			$prepared['final_path'],
+			$prepared['filename'],
+			$prepared['context'],
+			$prepared['post_id']
+		);
+
+		// Type-specific post-registration
+		if ($prepared['file_type'] === 'image') {
+			$alt_text = apply_filters('jvb_upload_alt_text', '', $prepared['context']);
+			if ($alt_text !== '') {
+				update_post_meta($attachment_id, '_wp_attachment_image_alt', $alt_text);
+			}
+		}
+
+		if ($prepared['file_type'] === 'video' && ($prepared['config']['extract_video_thumbnail'] ?? false)) {
+			$this->extractVideoThumbnail(
+				$attachment_id,
+				$prepared['final_path'],
+				$prepared['config']['video_thumbnail_time'] ?? 0
+			);
+		}
+
+		return [
+			'success'       => true,
+			'attachment_id' => $attachment_id,
+			'url'           => wp_get_attachment_url($attachment_id),
+			'file'          => $prepared['final_path'],
+			'type'          => $prepared['file_type'],
+		];
+	}
+
+	/**
+	 * Image file I/O: convert or copy to final location
+	 */
+	protected function prepareImage(string $original_path, string $directory, string $filename, array $config): string
+	{
+		$full_dir      = "{$this->upload_dir}/{$directory}";
+		$original_mime = mime_content_type($original_path);
+
+		$should_convert = false;
+		$target_format  = false;
+
+		if ($config['convert'] && $config['convert'] !== false) {
+			$target_format = strtolower($config['convert']);
+			if (!isset($this->supportedFormats[$target_format])) {
+				throw new Exception("Unsupported conversion format: {$target_format}");
+			}
+			$should_convert = ($original_mime !== $this->supportedFormats[$target_format]);
+		}
+
+		if ($should_convert) {
+			$final_path = "{$full_dir}/{$filename}.{$target_format}";
+			try {
+				$this->convertImage($original_path, $final_path, $target_format, $config['quality'], $config['use_imagick']);
+			} catch (Exception $e) {
+				JVB()->error()->log('Image conversion failed: ' . $e->getMessage());
+				$ext = pathinfo($original_path, PATHINFO_EXTENSION);
+				$final_path = "{$full_dir}/{$filename}.{$ext}";
+				copy($original_path, $final_path);
+			}
+		} else {
+			$ext = pathinfo($original_path, PATHINFO_EXTENSION);
+			$final_path = "{$full_dir}/{$filename}.{$ext}";
+			copy($original_path, $final_path);
+		}
+
+		return $final_path;
+	}
+
+	/**
+	 * Video/document file I/O: copy to final location
+	 */
+	protected function prepareMedia(string $original_path, string $directory, string $filename): string
+	{
+		$full_dir   = "{$this->upload_dir}/{$directory}";
+		$ext        = pathinfo($original_path, PATHINFO_EXTENSION);
+		$final_path = "{$full_dir}/{$filename}.{$ext}";
+
+		copy($original_path, $final_path);
+
+		return $final_path;
+	}
 }

--
Gitblit v1.10.0