From 5b50afdcafd150186ea5c7b0e1cad98065590b35 Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Fri, 28 Aug 2026 18:44:28 +0000
Subject: [PATCH] =A few more phpStorm suggestions, mainly in PHPDocs
---
inc/rest/routes/UploadRoutes.php | 571 +++-----------------------------------------------------
1 files changed, 34 insertions(+), 537 deletions(-)
diff --git a/inc/rest/routes/UploadRoutes.php b/inc/rest/routes/UploadRoutes.php
index 5222e4d..4b3128e 100644
--- a/inc/rest/routes/UploadRoutes.php
+++ b/inc/rest/routes/UploadRoutes.php
@@ -1,9 +1,9 @@
<?php
namespace JVBase\rest\routes;
-use JVBase\managers\queue\executors\UploadExecutor;
-use JVBase\managers\queue\mergers\UploadMerger;
-use JVBase\managers\queue\TypeConfig;
+use JVBase\Instance;
+use JVBase\managers\Errors;
+use JVBase\managers\queue\Queue;
use JVBase\registrar\Registrar;
use JVBase\rest\PermissionHandler;
use JVBase\rest\Rest;
@@ -12,7 +12,6 @@
use JVBase\rest\Route;
use WP_REST_Request;
use WP_REST_Response;
-use WP_Error;
use Exception;
if (!defined('ABSPATH')) {
@@ -20,71 +19,15 @@
}
class UploadRoutes extends Rest
{
+ use Instance;
public function __construct()
{
parent::__construct();
- add_action('init', [$this, 'registerUploadExecutors'], 5);
}
- /**
- * Register upload operation types with the queue's TypeRegistry
- */
- public function registerUploadExecutors(): void
- {
- $registry = JVB()->queue()->registry();
- $executor = new UploadExecutor();
- $merger = new UploadMerger('secured_files');
- // Image uploads - chunked at 5 files
- $registry->register('image_upload', new TypeConfig(
- mergeable: $merger,
- executor: $executor,
- chunkKey: 'secured_files',
- chunkSize: 3
- ));
-
- // Video uploads - one at a time (heavy processing)
- $registry->register('video_upload', new TypeConfig(
- mergeable: $merger,
- executor: $executor,
- chunkKey: 'secured_files',
- chunkSize: 1
- ));
-
- // Document uploads - chunked at 10
- $registry->register('document_upload', new TypeConfig(
- mergeable: $merger,
- executor: $executor,
- chunkKey: 'secured_files',
- chunkSize: 5
- ));
-
- // Metadata updates
- $registry->register('update_image_meta', new TypeConfig(
- executor: $executor
- ));
-
- // Cleanup - chunked at 5
- $registry->register('temporary_cleanup', new TypeConfig(
- executor: $executor,
- chunkKey: 'files',
- chunkSize: 5
- ));
-
- // Attach to content (depends on upload completing)
- $registry->register('attach_upload_to_content', new TypeConfig(
- executor: $executor
- ));
-
- // Process upload groups into posts
- $registry->register('process_upload_groups', new TypeConfig(
- executor: $executor,
- chunkKey: 'posts',
- chunkSize: 5
- ));
- }
/**
* Registers upload routes
@@ -105,7 +48,6 @@
->args([
'id' => 'string|required',
'content' => 'string|required',
- 'user' => 'int|required'
])
->register();
@@ -114,7 +56,6 @@
->auth(PermissionHandler::combine(['nonce']))
->rateLimit(30)
->args([
- 'user' => 'int|required',
'items' => 'array|required',
'id' => 'string'
])
@@ -125,6 +66,8 @@
* Build the main $context for UploadManager from the $request params
* @param WP_REST_Request $request
* @return array
+ * @throws Exception
+ * @throws Exception
*/
protected function buildUploadArgs(WP_REST_Request $request):array
{
@@ -174,15 +117,13 @@
break;
// User ID
case 'user':
- if ($this->userCheck($value)) {
- $args['user'] = (int) $value;
- if (!array_key_exists('post_id', $args) &&
- !array_key_exists('post_id', $data) &&
- !array_key_exists('term_id', $data) &&
- !array_key_exists('item_id', $data)) {
- $args['post_id'] = (int)get_user_meta((int) $value, BASE.'profile_link', true);
- }
+ if (!array_key_exists('post_id', $args) &&
+ !array_key_exists('post_id', $data) &&
+ !array_key_exists('term_id', $data) &&
+ !array_key_exists('item_id', $data)) {
+ $args['post_id'] = (int)get_user_meta((int) $value, BASE.'profile_link', true);
}
+
break;
// Operation ID
case 'id':
@@ -261,13 +202,13 @@
case 'field_key':
case 'field_type':
case 'subtype':
- case 'item_id':
case 'context':
if (is_string($value)) {
$args[$key] = sanitize_text_field($value);
}
break;
}
+ $args['user'] = get_current_user_id();
}
return $args;
}
@@ -286,8 +227,8 @@
$files = $request->get_file_params();
$args = $this->buildUploadArgs($request);
-
- if (!$args['user']) {
+ $userID = get_current_user_id();
+ if (!$userID) {
return $this->unauthorized();
}
if (!$args['content']) {
@@ -309,7 +250,7 @@
} catch (Exception $e) {
// Error handling...
- JVB()->error()->log(
+ Errors::getInstance()->log(
'[UploadRoutes]:handleUploadRequest',
$e->getMessage(),
[
@@ -327,7 +268,7 @@
*/
protected function secureFiles(array $files, array $args): array
{
- $uploader = new UploadManager();
+ $uploader = UploadManager::getInstance();
$secured_files = [];
$errors = [];
@@ -415,9 +356,9 @@
error_log('Queueing Operation: '.print_r($operation_type, true));
error_log('With ID: '.print_r($args['upload'], true));
- $queuedProcessing = JVB()->queue()->queueOperation(
+ $queuedProcessing = Queue::getInstance()->queueOperation(
$operation_type,
- $args['user'],
+ get_current_user_id(),
array_merge(
['secured_files' => $secured_data['files']],
$args
@@ -439,9 +380,9 @@
// When merged, the original upload's attach_upload_to_content
// will handle all files after the merged image_upload completes.
if (!$queuedProcessing['updated_existing']) {
- JVB()->queue()->queueOperation(
+ Queue::getInstance()->queueOperation(
'attach_upload_to_content',
- $args['user'],
+ get_current_user_id(),
$args,
[
'priority' => 'high',
@@ -452,21 +393,6 @@
}
}
- JVB()->queue()->queueOperation(
- 'temporary_cleanup',
- $args['user'],
- [
- 'files' => $secured_data['files'],
- 'context' => $args,
- ],
- [
- 'priority' => 'low',
- 'chunk_size' => 5,
- 'chunk_key' => 'files',
- 'depends_on' => [$uploadOpId]
- ]
- );
-
return $args['id'];
}
@@ -484,145 +410,8 @@
};
}
- /**
- * Step 3: Process operation from queue
- * Called by OperationQueue
- * @param WP_Error|array $result
- * @param object $operation
- * @param array $data
- *
- * @return array|WP_Error
- */
- public function processOperation(array $result, object $operation, array $data): array
- {
- // Only handle our operation types
- $handled_types = [
- 'image_upload',
- 'video_upload',
- 'document_upload',
- 'update_metadata',
- 'temporary_cleanup',
- 'attach_upload_to_content',
- 'process_upload_groups'
- ];
- if (!in_array($operation->type, $handled_types)) {
- return $result; // Not our operation, pass through
- }
- try {
- // Route to appropriate handler
- $handler_result = match($operation->type) {
- 'image_upload' => $this->processImageUpload($operation, $data),
- 'video_upload' => $this->processVideoUpload($operation, $data),
- 'document_upload' => $this->processDocumentUpload($operation, $data),
- 'update_metadata' => $this->processUploadMeta($result, $operation, $data),
- 'temporary_cleanup' => $this->processTemporaryCleanup($result, $operation, $data),
- 'attach_upload_to_content' => $this->processAttachToContent($operation, $data),
- 'process_upload_groups' => $this->processUploadGroups($result, $operation, $data),
- default => new WP_Error('unknown_type', 'Unknown operation type')
- };
-
- // Handle WP_Error
- if (is_wp_error($handler_result)) {
- return [
- 'success' => false,
- 'result' => $handler_result->get_error_message()
- ];
- }
-
- return $handler_result;
-
- } catch (Exception $e) {
- JVB()->error()->log(
- '[UploadRoutes]:processOperation',
- $e->getMessage(),
- [
- 'operation_id' => $operation->id,
- 'operation_type' => $operation->type
- ]
- );
-
- return [
- 'success' => false,
- 'result' => $e->getMessage()
- ];
- }
- }
- /**
- * Standardize processing result
- */
- protected function standardizeResult(array $result): array
- {
- return [
- 'attachment_id' => $result['attachment_id'],
- 'url' => $result['url'],
- 'file' => $result['file'],
- 'upload_id' => $result['upload_id'] ?? null
- ];
- }
-
- protected function processAttachToContent(object $operation, array $data): array
- {
- try {
- // Get the results from the upload operation
- $upload_results = JVB()->queue()->getOperationValue($data['upload'], 'result', true);
-
- if (empty($upload_results)) {
- throw new Exception('No upload results found for operation: ' . $data['upload']);
- }
-
- if (empty($data['post_id']) || str_starts_with((string)($data['item_id'] ?? ''), 'new')) {
- foreach ($operation->dependencies as $depId) {
- $dep = JVB()->queue()->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])) {
- $data['post_id'] = $dep->result['new_posts'][$itemId];
- break;
- }
- }
- }
-
- if (empty($data['post_id'])) {
- throw new Exception('Could not resolve post_id from dependencies');
- }
- }
-
- // Now attach to the specified content
- if (!empty($data['field_name'])) {
- $this->updateFieldValue($data, $upload_results);
- }
-
- return [
- 'success' => true,
- 'result' => 'Attachments linked to content'
- ];
-
- } catch (Exception $e) {
- return [
- 'success' => false,
- 'result' => $e->getMessage()
- ];
- }
- }
-
- /**
- * Cleanup temporary files after processing
- */
- protected function cleanupTempFiles(array $secured_files, int $user_id): void
- {
- $uploader = new UploadManager();
-
- foreach ($secured_files as $secured) {
- if (!empty($secured['temp_path']) && file_exists($secured['temp_path'])) {
- @unlink($secured['temp_path']);
- }
- }
-
- // Clean up empty directories
- $uploader->cleanupEmptyTempDirs($user_id);
- }
/**
* Update field value with new attachment IDs
@@ -654,159 +443,6 @@
$meta->set($data['field_name'], implode(',', $all_ids));
}
- /**
- * Generic file upload processor - works for images, videos, documents
- */
- protected function processFileUpload(object $operation, array $data, string $file_type): WP_Error|array
- {
- try {
- $uploader = new UploadManager();
- $processed_results = [];
- $config = $this->getFieldConfig($data);
-
- $args = $data;
- unset($args['secured_files']);
-
- foreach ($data['secured_files'] as $secured_file) {
- $result = $uploader->processUpload(
- $secured_file['temp_path'],
- array_merge(
- $config,
- [
- 'file_type' => $file_type,
- 'user_id' => $operation->user_id,
- 'post_id' => (int)($data['post_id'] ?? 0),
- 'term_id' => (int)($data['term_id'] ?? 0),
- 'original_name' => $secured_file['original_name'],
- 'mime_type' => $secured_file['mime_type'],
- 'content' => $data['content'] ?? '',
- ]
- )
- );
-
- if (!is_wp_error($result)) {
- $standardized = $this->standardizeResult($result);
-
- // Use embedded upload_id from the secured file itself
- $standardized['upload_id'] = $secured_file['upload_id'] ?? null;
-
- if ($standardized['upload_id']) {
- $processed_results[$standardized['upload_id']] = $standardized;
- } else {
- $processed_results[] = $standardized;
- }
-
- // Apply frontend metadata if provided
- if (!empty($secured_file['metadata'])) {
- $this->applyMeta($standardized['attachment_id'], $secured_file['metadata']);
- }
- }
- }
-
- $this->handleUploadDestination($data, $processed_results);
-
- // Cleanup temporary files
- $this->cleanupTempFiles($data['secured_files'], $operation->user_id);
-
- return [
- 'success' => true,
- 'result' => $processed_results
- ];
-
- } catch (Exception $e) {
- JVB()->error()->log(
- '[UploadRoutes]:processFileUpload',
- $e->getMessage(),
- [
- 'operation_id' => $operation->id,
- 'file_type' => $file_type,
- 'user_id' => $operation->user_id
- ]
- );
- return [
- 'success' => false,
- 'result' => $e->getMessage()
- ];
- }
- }
-
- /**
- * Process image uploads
- */
- protected function processImageUpload(object $operation, array $data): WP_Error|array
- {
- return $this->processFileUpload($operation, $data, 'image');
- }
-
- /**
- * Process video uploads
- */
- protected function processVideoUpload(object $operation, array $data): WP_Error|array
- {
- return $this->processFileUpload($operation, $data, 'video');
- }
-
- /**
- * Process document uploads
- */
- protected function processDocumentUpload(object $operation, array $data): WP_Error|array
- {
- return $this->processFileUpload($operation, $data, 'document');
- }
-
- /**
- * Process temporary cleanup operation
- * Called by OperationQueue for 'temporary_cleanup' operations
- *
- * @param array $result
- * @param object $operation
- * @param array $data
- * @return array
- */
- protected function processTemporaryCleanup(array $result, object $operation, array $data): array
- {
- try {
- // Cleanup temporary files if they exist
- if (!empty($data['secured_files'])) {
- $this->cleanupTempFiles($data['secured_files'], $operation->user_id);
- }
-
- // If specific temp paths provided
- if (!empty($data['temp_paths']) && is_array($data['temp_paths'])) {
- foreach ($data['temp_paths'] as $temp_path) {
- if (file_exists($temp_path)) {
- @unlink($temp_path);
- }
- }
- }
-
- // Cleanup empty temp directories for this user
- if (!empty($operation->user_id)) {
- $uploader = new UploadManager();
- $uploader->cleanupEmptyTempDirs($operation->user_id);
- }
-
- return [
- 'success' => true,
- 'result' => 'Temporary files cleaned up successfully'
- ];
-
- } catch (Exception $e) {
- JVB()->error()->log(
- '[UploadRoutes]:processTemporaryCleanup',
- $e->getMessage(),
- [
- 'operation_id' => $operation->id,
- 'user_id' => $operation->user_id
- ]
- );
-
- return [
- 'success' => false,
- 'result' => $e->getMessage()
- ];
- }
- }
/**
* Handle metadata update requests
@@ -840,6 +476,8 @@
}
+
+
return $this->sendResponse(
false,
['error_code' => 'missing_identifiers'],
@@ -847,7 +485,7 @@
);
} catch (Exception $e) {
- JVB()->error()->log(
+ Errors::getInstance()->log(
'[UploadRoutes]:handleMetadataUpdate',
$e->getMessage(),
[
@@ -908,7 +546,7 @@
*/
protected function queueMetaUpdate(array $data, int $user, ?string $operationId = null): WP_REST_Response
{
- $queue = JVB()->queue();
+ $queue = Queue::getInstance();
$depends_on = [];
$errors = [];
$original = count($data);
@@ -940,76 +578,7 @@
);
}
- /**
- * Process metadata update operation (called by queue processor)
- */
- public function processUploadMeta(WP_Error|array $result, object $operation, array $data): WP_Error|array
- {
- try {
- if (!is_array($operation->depends_on)) {
- $operation->depends_on = [$operation->depends_on];
- }
- $updated_count = 0;
- $errors = [];
- foreach ($operation->depends_on as $dependency) {
- $operationData = JVB()->queue()->getOperation($dependency);
- if (!$operationData || $operationData->state !== 'completed') {
- throw new Exception('Original upload operation not found or not completed');
- }
- $uploadResults = json_decode($operationData->result, true);
- if (!$uploadResults || !$uploadResults['success']) {
- throw new Exception('Original upload operation failed');
- }
- $attachmentsToUpdate = array_filter($data, function ($item) use ($dependency) {
- return $item['depends_on'] === $dependency;
- });
-
- $uploadIDToAttachment = $this->buildUploadToAttachmentMapping(
- array_keys($attachmentsToUpdate),
- $uploadResults['data']
- );
-
- if (empty($uploadIDToAttachment)) {
- throw new Exception('No valid upload ID to attachment ID mappings found');
- }
-
- foreach ($uploadIDToAttachment as $uploadId => $attachmentId) {
- try {
- $this->applyMeta($attachmentId, $attachmentsToUpdate[$uploadId]);
- $updated_count++;
- } catch (Exception $e) {
- $errors[] = "Upload {$uploadId} (Attachment {$attachmentId}): " . $e->getMessage();
- }
- }
- }
-
- return [
- 'success' => $updated_count > 0,
- 'result' => [
- 'updated_count' => $updated_count,
- 'mappings' => $uploadIDToAttachment,
- 'errors' => $errors,
- 'message' => "Applied metadata to {$updated_count} attachment(s)"
- ]
- ];
-
- } catch (Exception $e) {
- JVB()->error()->log(
- '[UploadRoutes]:processUploadMeta',
- $e->getMessage(),
- [
- 'operation_id' => $operation->id,
- 'original_operation_id' => $data['original_operation_id'] ?? 'unknown'
- ]
- );
-
- return [
- 'success' => false,
- 'result' => $e->getMessage()
- ];
- }
- }
protected function applyMeta(int $attachment_id, array $metadata): void
{
@@ -1035,31 +604,9 @@
}
/**
- * Build mapping from frontend upload IDs to WordPress attachment IDs
- */
- protected function buildUploadToAttachmentMapping(array $upload_ids, array $results): array
- {
- $mapping = [];
-
- foreach ($results as $result) {
- if (!isset($result['upload_id']) || !isset($result['attachment_id'])) {
- continue;
- }
-
- $upload_id = $result['upload_id'];
- $attachment_id = $result['attachment_id'];
-
- // Validate that this upload_id was requested
- if (in_array($upload_id, $upload_ids)) {
- $mapping[$upload_id] = $attachment_id;
- }
- }
-
- return $mapping;
- }
-
- /**
- * Verify user has access to attachment
+ * @param int $attachment_id
+ * @param int $user_id
+ * @return bool
*/
protected function verifyAttachmentAccess(int $attachment_id, int $user_id): bool
{
@@ -1074,59 +621,9 @@
}
/**
- * Get field configuration for upload processing
- */
- protected function getFieldConfig(array $data): array
- {
- static $config_cache = [];
-
- $cache_key = md5(json_encode([
- $args['content'] ?? '',
- $args['field_name'] ?? ''
- ]));
-
- if (isset($config_cache[$cache_key])) {
- return $config_cache[$cache_key];
- }
-
- $config = [
- 'allowed_types' => null,
- 'max_size' => null,
- 'convert' => 'webp',
- 'quality' => 80,
- 'create_thumbnails' => true,
- ];
-
- // Get field definition from registry if available
- if (!empty($args['content']) && !empty($args['field_name'])) {
- $content_type = $args['content'];
- $field_name = $args['field_name'];
- $registrar = Registrar::getInstance($content_type);
- if ($registrar) {
- $content_fields = $registrar->getFields();
- if (array_key_exists($field_name, $content_fields)) {
- $field_def = $content_fields[$field_name];
-
- // Extract relevant config from field definition
- $config = array_merge($config, [
- 'allowed_types' => $field_def['accepted_types'] ?? null,
- 'max_size' => $field_def['max_size'] ?? null,
- 'convert' => $field_def['convert'] ?? 'webp',
- 'quality' => $field_def['quality'] ?? 80,
- 'create_thumbnails' => $field_def['create_thumbnails'] ?? true,
- ]);
- }
- }
- }
-
- $config_cache[$cache_key] = $config;
- return $config;
- }
-
-
-
- /**
* Get files info for error logging
+ * @param array $files
+ * @return array
*/
protected function getFilesInfo(array $files): array
{
@@ -1159,7 +656,7 @@
$files = $request->get_file_params();
$args = $this->buildUploadArgs($request);
- if (!array_key_exists('user', $args) || $args['user'] === 0){
+ if (!$args['user']) {
return $this->unauthorized();
}
if (!array_key_exists('content', $args) || empty($args['content'])) {
@@ -1185,7 +682,7 @@
$chunkSize = 10;
}
- JVB()->queue()->queueOperation(
+ Queue::getInstance()->queueOperation(
$operation_type,
$args['user'],
array_merge(
@@ -1199,7 +696,7 @@
]
);
- $ID = JVB()->queue()->queueOperation(
+ $ID = Queue::getInstance()->queueOperation(
'process_upload_groups',
$args['user'],
$args,
@@ -1213,7 +710,7 @@
return $this->queued($ID['operation_id'], 'Files uploaded and posts queued for creation');
} catch (Exception $e) {
- JVB()->error()->log(
+ Errors::getInstance()->log(
'[UploadRoutes]:handleGroupingRequest',
$e->getMessage(),
[
--
Gitblit v1.10.0