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/queue/executors/ContentExecutor.php | 347 ++++++++++++++++++++++++++++++++++++++++++---------------
1 files changed, 254 insertions(+), 93 deletions(-)
diff --git a/inc/managers/queue/executors/ContentExecutor.php b/inc/managers/queue/executors/ContentExecutor.php
index d9a8e11..55835f0 100644
--- a/inc/managers/queue/executors/ContentExecutor.php
+++ b/inc/managers/queue/executors/ContentExecutor.php
@@ -3,7 +3,7 @@
use JVBase\managers\queue\{Executor, Operation, Progress, Result, Storage};
use JVBase\meta\Meta;
-use JVBase\utility\Features;
+use JVBase\registrar\Registrar;
use Exception;
if (!defined('ABSPATH')) {
@@ -32,6 +32,7 @@
if (!in_array($operation->type, self::HANDLED_TYPES)) {
throw new Exception("ContentExecutor cannot handle type: {$operation->type}");
}
+ error_log('Executing ContentExecutor.php');
try {
$data = $operation->requestData;
@@ -66,102 +67,59 @@
private function processContentUpdate(Operation $operation, array $data, Progress $progress): Result
{
$posts = $data['posts'] ?? [];
-
+ error_log('Processing Content Update: '.print_r($posts, true));
if (empty($posts)) {
return new Result(
- outcome: 'failed',
+ outcome: 'success',
result: ['message' => 'No posts to update']
);
}
- $results = [];
+ $results = [
+ 'errors' => [],
+ 'success' => [],
+ 'newPosts' => [],
+ 'timelineParents' => [],
+ 'timelineStatus' => [],
+ 'timelineSharedFields' => [],
+ ];
$errors = [];
- $success = [];
- $timelineParents = [];
- $timelineStatus = [];
- $timelineSharedFields = [];
- $newPostsMap = [];
foreach ($posts as $id => $postData) {
try {
- $content = $postData['content'] ?? '';
-
- // New post creation
- if (str_starts_with((string)$id, 'new')) {
- $newId = wp_insert_post([
- 'post_author' => $this->userId,
- 'post_type' => jvbCheckBase($content),
- 'post_title' => $postData['post_title'] ?? '',
- 'post_status' => $postData['status'] ?? 'draft',
- ]);
-
- if (!$newId || is_wp_error($newId)) {
- $errors[$id] = 'Could not create post';
- $progress->failItem($id, 'Could not create post');
- continue;
- }
-
- $newPostsMap[$id] = $newId;
- $this->savePostFields($newId, $postData);
- $success[$newId] = array_keys($postData);
- $progress->advance();
- continue;
+ $content = $postData['content'] ?? false;
+ if (!$content) continue;
+ $registrar = Registrar::getInstance($content);
+ switch ($registrar->getType()) {
+ case 'post':
+ $results = $this->handlePost($id, $postData, $registrar, $results, $progress);
+ break;
+ case 'term':
+ $results = $this->handleTerm($id, $postData, $registrar, $results, $progress);
+ break;
+ case 'user':
+ $results = $this->handleUser($id, $postData, $registrar, $results, $progress);
+ break;
}
-
- // Existing post update
- if (!$this->verifyOwnership((int)$id)) {
- $progress->failItem($id, 'No permission to modify this post');
- $errors[$id] = 'No permission';
- continue;
- }
-
- $this->savePostFields((int)$id, $postData);
-
- if (Features::forContent($content)->has('is_timeline')) {
- $post = get_post((int)$id);
- $parentId = $post->post_parent > 0 ? $post->post_parent : $post->ID;
- $sharedFields = array_keys(array_filter(JVB_CONTENT[$content]['fields'], function ($field) {
- return !array_key_exists('for_all', $field) || !$field['for_all'];
- }));
-
- if (array_key_exists('post_date', $postData) && !in_array($parentId, $timelineParents)) {
- $timelineParents[] = $parentId;
- }
- if ($parentId === $id) {
- if (array_key_exists('post_status', $postData) && !array_key_exists($parentId, $timelineStatus)) {
- $timelineStatus[$parentId] = $postData['post_status'];
- }
-
- if (count(array_intersect($sharedFields, array_keys($postData))) > 0) {
- if (!array_key_exists($parentId, $timelineSharedFields)) {
- $timelineSharedFields[$parentId] = [];
- }
- $temp = array_intersect($sharedFields, array_keys($postData));
- $timelineSharedFields[$parentId] = array_unique(array_merge($timelineSharedFields[$parentId], $temp));
- }
- }
- }
-
- $success[$id] = array_keys($postData);
- $progress->advance();
} catch (Exception $e) {
$progress->failItem($id, $e->getMessage());
- $errors[$id] = $e->getMessage();
+ $results['errors'][$id] = $e->getMessage();
}
}
+ error_log('Final Results: '.print_r($results, true));
try {
- if (!empty($timelineSharedFields)) {
- $this->checkSharedFields($timelineSharedFields);
+ if (!empty($results['timelineSharedFields'])) {
+ $this->checkSharedFields($results['timelineSharedFields']);
}
- if (!empty($timelineStatus)) {
- $this->handleTimelineStatusChange($timelineStatus);
+ if (!empty($results['timelineStatus'])) {
+ $this->handleTimelineStatusChange($results['timelineStatus']);
}
- if (!empty($timelineParents)) {
- $this->maybeReorderTimelines($timelineParents);
+ if (!empty($results['timelineParents'])) {
+ $this->maybeReorderTimelines($results['timelineParents']);
}
} catch (Exception $e) {
- $errors[] = $e->getMessage();
+ $results['errors'][] = $e->getMessage();
}
@@ -182,33 +140,85 @@
return new Result(
outcome: $outcome,
- result: [
- 'posts' => $success,
- 'errors' => $errors,
- 'new_posts' => $newPostsMap,
- 'updated_count' => count($success),
- 'failed_count' => count($errors)
- ]
+ result: $results,
);
}
private function savePostFields(int $postId, array $postData): bool
{
$content = $postData['content'] ?? '';
- $fields = jvbGetFields($content);
+ $fields = Registrar::getFieldsFor($content);
$allowedFields = array_filter($postData, function ($key) use ($fields) {
return array_key_exists($key, $fields);
}, ARRAY_FILTER_USE_KEY);
+ //Remove values that are already saved
+ $check = Meta::forPost($postId)->getAll(array_keys($allowedFields));
+ error_log('Stored values: '.print_r($check, true));
+ $allowedFields = array_filter($allowedFields, function ($key) use ($allowedFields, $check) {
+ return $allowedFields[$key] !== $check[$key];
+ }, ARRAY_FILTER_USE_KEY);
+
if (empty($allowedFields)) {
return true;
}
return Meta::forPost($postId)
- ->setAll($allowedFields)
- ->save();
+ ->setAll($allowedFields);
}
+ private function saveTermFields(int $termId, array $data): bool
+ {
+ $content = $data['content'] ?? '';
+ error_log('Saving term fields: '.print_r($data, true));
+ $fields = Registrar::getFieldsFor($content);
+
+ $allowedFields = array_filter($data, function ($key) use ($fields) {
+ return array_key_exists($key, $fields);
+ }, ARRAY_FILTER_USE_KEY);
+
+
+ //Remove values that are already saved
+ $check = Meta::forTerm($termId)->getAll(array_keys($allowedFields));
+ error_log('Stored values: '.print_r($check, true));
+ $allowedFields = array_filter($allowedFields, function ($value, $key) use ($check) {
+ error_log('Sent value: '.print_r($value, true));
+ error_log('Stored Value: '.print_r($check[$key], true));
+ return $value !== $check[$key];
+ }, ARRAY_FILTER_USE_BOTH);
+
+ if (empty($allowedFields)) {
+ return true;
+ }
+
+ error_log('Allowed fields: '.print_r($allowedFields, true));
+
+ return Meta::forTerm($termId)
+ ->setAll($allowedFields);
+ }
+ private function saveUserFields(int $userId, array $data): bool
+ {
+ $content = $data['content'] ?? '';
+ $fields = Registrar::getFieldsFor($content);
+
+ $allowedFields = array_filter($data, function ($key) use ($fields) {
+ return array_key_exists($key, $fields);
+ }, ARRAY_FILTER_USE_KEY);
+
+ //Remove values that are already saved
+ $check = Meta::forUser($userId)->getAll(array_keys($allowedFields));
+ $allowedFields = array_filter($allowedFields, function ($key) use ($allowedFields, $check) {
+ return $allowedFields[$key] !== $check[$key];
+ }, ARRAY_FILTER_USE_KEY);
+
+ if (empty($allowedFields)) {
+ return true;
+ }
+
+ return Meta::forUser($userId)
+ ->setAll($allowedFields);
+ }
+
// ─────────────────────────────────────────────────────────────
// Helpers
@@ -232,12 +242,11 @@
}
}
}
- protected function maybeReorderTimeline(int $parentID):void
+ protected function getTimelinePosts(int $parentID):array
{
-// clean_post_cache($parentID);
$parent = get_post($parentID);
if (!$parent) {
- return;
+ return [];
}
$children = get_children([
@@ -248,7 +257,7 @@
if (count($children) === 0) {
- return;
+ return [];
}
$allPosts = array_merge([$parent], $children);
@@ -258,6 +267,22 @@
return strtotime($a->post_date) <=> strtotime($b->post_date);
});
+ return $allPosts;
+ }
+ protected function maybeReorderTimeline(int $parentID):void
+ {
+// clean_post_cache($parentID);
+ $parent = get_post($parentID);
+ if (!$parent) {
+ return;
+ }
+
+ $allPosts = $this->getTimelinePosts($parentID);
+ if (empty($allPosts)) {
+ return;
+ }
+
+
// Check if order changed
$needsReorder = false;
@@ -323,11 +348,14 @@
}
}
}
+ $isUpdate = $meta->get('is_update');
+ if (!(bool) $isUpdate) {
+ $meta->set('number', $index);
+ }
if ($lastKey === $index) {
$latestTimestamp = strtotime($post->post_date);
}
- $meta->save();
$previousPost = $post;
}
@@ -448,8 +476,7 @@
}
foreach ($children as $child) {
- $childMeta = Meta::forPost($child);
- $result = $childMeta->setAll($values, false);
+ Meta::forPost($child)->setAll($values);
}
}
}
@@ -483,4 +510,138 @@
}
}
}
+
+ protected function handlePost(string|int $ID, array $data, Registrar $registrar, array $results, Progress $progress):array
+ {
+ // New post creation
+ if (str_starts_with((string)$ID, 'new')) {
+
+ $newId = wp_insert_post([
+ 'post_author' => $this->userId,
+ 'post_type' => $registrar->getBased(),
+ 'post_title' => $data['post_title'] ?? apply_filters('jvbDefaultTitle', '', $registrar->getSlug()),
+ 'post_status' => $data['status'] ?? 'draft',
+ ]);
+ error_log('Created new post: '.print_r($newId, true));
+
+ if (!$newId || is_wp_error($newId)) {
+ $results['errors'][$ID] = 'Could not create post';
+ $progress->failItem($ID, 'Could not create post');
+ return $results;
+ }
+
+ $results['newPosts'][$ID] = $newId;
+ $this->savePostFields($newId, $data);
+ unset($data['content']);
+ $results['success'][$newId] = $data;
+ $progress->advance();
+ return $results;
+ }
+
+ //Existing post update
+ if (!$this->verifyOwnership((int)$ID)) {
+ $progress->failItem($ID, 'No permission to modify this post');
+ $results['errors'][$ID] = 'No permission';
+ return $results;
+ }
+
+ $result = $this->savePostFields((int)$ID, $data);
+ unset($data['content']);
+ if ($result) {
+ $results['success'][$ID] = $data;
+ } else {
+ $results['errors'][$ID] = 'Could not update post data';
+ }
+ if ($registrar && $registrar->hasFeature('is_timeline')) {
+ $post = get_post((int)$ID);
+ $parentId = $post->post_parent > 0 ? $post->post_parent : $post->ID;
+ $fields = $registrar->getFields();
+ $sharedFields = array_keys(array_filter($fields, function ($field) {
+ return !array_key_exists('for_all', $field) || !$field['for_all'];
+ }));
+
+
+ if (array_key_exists('timeline_gallery', $data)) {
+ //This should only happen if we delete an image from the gallery
+ $changes = explode(',', $data['timeline_gallery']);
+ $timelinePosts = $this->getTimelinePosts($parentId);
+ if (!empty($timelinePosts)) {
+ $posts = array_map(function($item) { return $item->ID; }, $timelinePosts);
+ $changed = false;
+ foreach ($posts as $tID) {
+ if (!in_array($tID, $changes)) {
+ $changed = true;
+ wp_delete_post($tID, true);
+ }
+ }
+ if ($changed) {
+ $results['timelineParents'][] = $parentId;
+ }
+ }
+
+ }
+
+
+ if (array_key_exists('post_date', $data) && !in_array($parentId, $results['timelineParents'])) {
+ $results['timelineParents'][] = $parentId;
+ }
+ if ($parentId === $ID) {
+ if (array_key_exists('post_status', $data) && !array_key_exists($parentId, $results['timelineStatus'])) {
+ $results['timelineStatus'][$parentId] = $data['post_status'];
+ }
+
+ if (count(array_intersect($sharedFields, array_keys($data))) > 0) {
+ if (!array_key_exists($parentId, $results['timelineSharedFields'])) {
+ $results['timelineSharedFields'][$parentId] = [];
+ }
+ $temp = array_intersect($sharedFields, array_keys($data));
+ $results['timelineSharedFields'][$parentId] = array_unique(array_merge($results['timelineSharedFields'][$parentId], $temp));
+ }
+ }
+ }
+ $progress->advance();
+ return $results;
+ }
+
+
+ protected function handleTerm(int $ID, array $data, Registrar $registrar, array $results, Progress $progress):array
+ {
+ error_log('Handling term '.$ID.' with data: '.print_r($data, true));
+ //Existing term update
+ if ($registrar->hasFeature('is_ownable') && (!JVB()->roles()->isOwner($this->userId, $ID) && !JVB()->roles()->isManager($this->userId, $ID))) {
+ error_log('Term is ownable. User does not own this term.');
+ $progress->failItem($ID, 'No permission to modify this term');
+ $results['errors'][$ID] = 'No permission';
+ return $results;
+ }
+
+ $result = $this->saveTermFields($ID, $data);
+ unset($data['content']);
+ if ($result) {
+ $results['success'][$ID] = $data;
+ } else {
+ $results['errors'][$ID] = 'Could not update term data';
+ }
+ $progress->advance();
+ return $results;
+ }
+ protected function handleUser(int $ID, array $data, Registrar $registrar, array $results, Progress $progress):array
+ {
+ //Existing term update
+ if ($ID !== $this->userId || !user_can($this->userId, 'manage_options')) {
+ $progress->failItem($ID, 'No permission to modify this term');
+ $results['errors'][$ID] = 'No permission';
+ return $results;
+ }
+
+ $result = $this->saveUserFields($ID, $data);
+ unset($data['content']);
+ if ($result) {
+ $results['success'][$ID] = $data;
+ } else {
+ $results['errors'][$ID] = 'Could not update post data';
+ }
+ $progress->advance();
+ return $results;
+ }
}
--
Gitblit v1.10.0