From ba1e1ccf869b818f7a7a897264dfea05563a7796 Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Sun, 07 Jun 2026 20:10:20 +0000
Subject: [PATCH] =Major overhaul of Integrations. Playing around with adding fields to post types through Registrar from an integrations' class file.

---
 inc/meta/Storage.php |  142 +++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 125 insertions(+), 17 deletions(-)

diff --git a/inc/meta/Storage.php b/inc/meta/Storage.php
index 30160a9..386b7b4 100644
--- a/inc/meta/Storage.php
+++ b/inc/meta/Storage.php
@@ -2,6 +2,7 @@
 namespace JVBase\meta;
 
 use Exception;
+use JVBase\managers\Cache;
 
 if (!defined('ABSPATH')) {
 	exit;
@@ -34,6 +35,16 @@
 			return $this->getWpDefault($item, $name);
 		}
 
+		// Taxonomy fields are stored in term_relationships, not meta
+		$config = $item->getFieldConfig($name);
+		if ($config
+			&& (
+				($config['type'] ?? '') === 'taxonomy'
+				|| (($config['type']??'') === 'selector' && ($config['subtype']??'') === 'taxonomy')
+			) && !isset($config['taxonomy_type'])) {
+			return $this->getTaxonomyField($item, $config);
+		}
+
 		$metaKey = BASE . $name;
 
 		return match ($item->objectType) {
@@ -56,23 +67,52 @@
 
 		$defaults = Item::WP_DEFAULTS[$item->objectType] ?? [];
 		$wpFields = array_intersect($defaults, $fieldNames);
-		$metaFields = array_diff($fieldNames, $wpFields);
+
+		// Separate taxonomy fields from regular meta fields
+		$taxonomyFields = [];
+		$metaFields = [];
+		foreach (array_diff($fieldNames, $wpFields) as $name) {
+			$config = $item->getFieldConfig($name);
+			if ($config
+				&& (
+					($config['type'] ?? '') === 'taxonomy'
+					|| (($config['type']??'') === 'selector' && ($config['subtype']??'') === 'taxonomy')
+				) && (!isset($config['taxonomy_type']) || !isset($config['isReference']))) {
+				$taxonomyFields[$name] = $config;
+			} else {
+				$metaFields[] = $name;
+			}
+		}
 
 		$values = [];
 
-		// Get meta fields in bulk query
 		if (!empty($metaFields)) {
 			$values = $this->bulkGetMeta($item, $metaFields);
 		}
 
-		// Get WP default fields
 		foreach ($wpFields as $name) {
 			$values[$name] = $this->getWpDefault($item, $name);
 		}
 
+		foreach ($taxonomyFields as $name => $config) {
+			$values[$name] = $this->getTaxonomyField($item, $config);
+		}
+
 		return $values;
 	}
 
+	protected function getTaxonomyField(Item $item, array $config): string
+	{
+		$taxonomy = jvbCheckBase($config['taxonomy']);
+		$terms = wp_get_object_terms($item->id, $taxonomy, ['fields' => 'ids']);
+
+		if (is_wp_error($terms) || empty($terms)) {
+			return '';
+		}
+
+		return implode(',', $terms);
+	}
+
 	/**
 	 * Save a single field
 	 */
@@ -83,18 +123,21 @@
 		}
 
 		if ($field->isTaxonomy()) {
+			error_log('Saving Taxonomy field with set_object_terms');
 			return $this->saveTaxonomyField($item, $field);
 		}
 
 		$metaKey = BASE . $field->name;
-
-		return match ($item->objectType) {
-			'post' => update_post_meta($item->id, $metaKey, $field->value) !== false,
-			'term' => update_term_meta($item->id, $metaKey, $field->value) !== false,
-			'user', 'integrations' => update_user_meta($item->id, $metaKey, $field->value) !== false,
+		$result =  match ($item->objectType) {
+			'post' => (bool)update_post_meta($item->id, $metaKey, $field->value),
+			'term' => (bool)update_term_meta($item->id, $metaKey, $field->value),
+			'user', 'integrations' => (bool)update_user_meta($item->id, $metaKey, $field->value),
 			'options' => $this->saveOption($item, $field),
 			default => false
 		};
+
+		error_log('Result: '.print_r($result, true));
+		return $result;
 	}
 
 	/**
@@ -109,10 +152,10 @@
 		}
 
 		$this->wpdb->query('START TRANSACTION');
-
 		try {
 			foreach ($dirty as $field) {
 				if (!$this->saveField($item, $field)) {
+					error_log("Could not save field: {$field->name}");
 					throw new Exception("Failed to save field: {$field->name}");
 				}
 				$field->markClean();
@@ -121,10 +164,7 @@
 			$this->wpdb->query('COMMIT');
 
 			// Update post modified timestamp
-			if ($updateTimestamp && $item->objectType === 'post' && $item->id) {
-				wp_update_post(['ID' => $item->id]);
-			}
-
+			Cache::invalidateItem($item->objectType, $item->id);
 			$this->clearCache($item);
 
 			return true;
@@ -394,7 +434,7 @@
 	{
 		return match ($name) {
 			'post_title' => get_the_title($item->id),
-			'post_excerpt' => get_the_excerpt($item->id),
+			'post_excerpt' => has_excerpt($item->id) ? get_the_excerpt($item->id):'',
 			'post_content' => get_post_field('post_content', $item->id),
 			default => $item->wpObject->$name ?? ''
 		};
@@ -403,7 +443,7 @@
 	protected function getTermField(Item $item, string $name): mixed
 	{
 		return match ($name) {
-			'term_name' => get_term_field('name', $item->id),
+			'name' => get_term_field('name', $item->id),
 			'description' => get_term_field('description', $item->id),
 			default => ''
 		};
@@ -426,9 +466,17 @@
 		$value = $field->value;
 
 		if (in_array($name, ['featured_image', 'post_thumbnail'])) {
+			if (empty($value)) {
+				return delete_post_thumbnail($item->id);
+			}
 			return set_post_thumbnail($item->id, $value) !== false;
 		}
 
+		// Special handling for post_status (trash/delete require specific functions)
+		if ($item->objectType === 'post' && $name === 'post_status') {
+			return $this->updatePostStatus($item->id, $value);
+		}
+
 		return match ($item->objectType) {
 			'post' => wp_update_post(['ID' => $item->id, $name => $value]) !== 0,
 			'term' => !is_wp_error(wp_update_term($item->id, $item->wpObject->taxonomy, [
@@ -440,11 +488,59 @@
 		};
 	}
 
+	/**
+	 * Update post status with proper WordPress functions
+	 *
+	 * WordPress doesn't handle trash/delete via wp_update_post():
+	 * - wp_trash_post() required for trashing
+	 * - wp_delete_post() required for deletion
+	 * - 'delete' is not even a valid post_status value
+	 *
+	 * @param int $postId Post ID
+	 * @param string $status New status (trash, delete, publish, draft, etc.)
+	 * @return bool Success
+	 */
+	protected function updatePostStatus(int $postId, string $status): bool
+	{
+		// Handle trash status
+		if ($status === 'trash') {
+			$result = wp_trash_post($postId);
+			if ($result === false || $result === null) {
+				error_log("[Storage] Failed to trash post {$postId}");
+				return false;
+			}
+			return true;
+		}
+
+		// Handle permanent deletion
+		if ($status === 'delete') {
+			$result = wp_delete_post($postId, true); // true = force delete, bypass trash
+			if ($result === false || $result === null) {
+				error_log("[Storage] Failed to delete post {$postId}");
+				return false;
+			}
+			return true;
+		}
+
+		// Handle all other statuses (publish, draft, pending, private, future)
+		$result = wp_update_post([
+			'ID' => $postId,
+			'post_status' => $status
+		]);
+
+		if ($result === 0 || is_wp_error($result)) {
+			$error = is_wp_error($result) ? $result->get_error_message() : 'Unknown error';
+			error_log("[Storage] Failed to update post {$postId} status to {$status}: {$error}");
+			return false;
+		}
+
+		return true;
+	}
+
 	protected function saveTaxonomyField(Item $item, Field $field): bool
 	{
 		$taxonomy = jvbCheckBase($field->config['taxonomy']);
 		$value = $field->value;
-
 		if (empty(trim((string)$value))) {
 			wp_set_object_terms($item->id, [], $taxonomy, false);
 			return true;
@@ -644,8 +740,20 @@
 				set_post_thumbnail($id, $fields['post_thumbnail']);
 				unset($fields['post_thumbnail']);
 			}
+			if (isset($fields['post_thumbnail'])) {
+				if (empty($fields['post_thumbnail'])) {
+					delete_post_thumbnail($id);
+				} else {
+					set_post_thumbnail($id, $fields['post_thumbnail']);
+				}
+				unset($fields['post_thumbnail']);
+			}
 			if (isset($fields['featured_image'])) {
-				set_post_thumbnail($id, $fields['featured_image']);
+				if (empty($fields['featured_image'])) {
+					delete_post_thumbnail($id);
+				} else {
+					set_post_thumbnail($id, $fields['featured_image']);
+				}
 				unset($fields['featured_image']);
 			}
 

--
Gitblit v1.10.0