From 474109a5df0a06f5343ab184838fe2d80e3872a8 Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Sun, 11 Jan 2026 19:23:20 +0000
Subject: [PATCH] =Fixed timeline CRUD.js issue where this.activeItem was set null when we still needed it
---
inc/rest/routes/ContentRoutes.php | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 103 insertions(+), 4 deletions(-)
diff --git a/inc/rest/routes/ContentRoutes.php b/inc/rest/routes/ContentRoutes.php
index 9a1eae9..38f9ddc 100644
--- a/inc/rest/routes/ContentRoutes.php
+++ b/inc/rest/routes/ContentRoutes.php
@@ -274,14 +274,14 @@
if (array_key_exists('taxonomies', $params)) {
$args = $this->applyTaxonomyFilters($args, $params);
}
- if (array_key_exists('date', $params) && !empty($params['date'])) {
+ if (array_key_exists('date-filter', $params) || array_key_exists('dateFrom', $params)) {
$args = $this->applyDateFilters($args, $params);
}
if (array_key_exists('orderby', $params) || array_key_exists('order', $params)) {
$args = $this->applyOrderFilters($args, $params);
}
- if (!empty($params['search'])) {
+ if (array_key_exists('search', $params)) {
$args['s'] = sanitize_text_field($params['search']);
}
@@ -302,10 +302,15 @@
return $this->addCacheHeaders($response);
}
+ $this->post_type = jvbCheckBase($params['content']??$params['type']);
+ // Only expand search to taxonomies if we're actually going to query
+ if (array_key_exists('s', $args)) {
+ $args = $this->applySearchFilters($args, $params);
+ }
+
// Run query
$query = new WP_Query($args);
- $this->post_type = $params['content']??$params['type'];
$this->fields = jvbGetFields(str_replace('-','_',$this->post_type));
$this->taxonomies = $this->getTaxonomies($this->post_type);
@@ -325,6 +330,87 @@
return $this->addCacheHeaders($response);
}
+ protected function applySearchFilters(array $args, array $params): array
+ {
+ $search_term = sanitize_text_field($params['search']);
+
+ // Search term is already in $args['s'] from earlier
+
+ // Get all taxonomies registered to this post type
+ $taxonomies = get_object_taxonomies($this->post_type, 'names');
+
+ if (empty($taxonomies)) {
+ return $args;
+ }
+
+ // Cache the taxonomy term lookup per search term + post type
+ $term_cache_key = 'search_terms_' . md5($search_term . $this->post_type);
+ $matching_term_ids = $this->cache->get($term_cache_key);
+
+ if ($matching_term_ids === false) {
+ $matching_term_ids = [];
+
+ foreach ($taxonomies as $taxonomy) {
+ $terms = get_terms([
+ 'taxonomy' => $taxonomy,
+ 'search' => $search_term,
+ 'hide_empty' => false,
+ 'fields' => 'ids'
+ ]);
+
+ if (!is_wp_error($terms) && !empty($terms)) {
+ $matching_term_ids = array_merge($matching_term_ids, $terms);
+ }
+ }
+
+ // Cache term IDs for 1 hour
+ $this->cache->set($term_cache_key, $matching_term_ids, 3600);
+ }
+
+ if (empty($matching_term_ids)) {
+ return $args;
+ }
+
+ // Build tax_query for matching terms
+ $term_queries = [];
+
+ foreach ($taxonomies as $taxonomy) {
+ $taxonomy_term_ids = array_filter($matching_term_ids, function($term_id) use ($taxonomy) {
+ $term = get_term($term_id);
+ return !is_wp_error($term) && $term->taxonomy === $taxonomy;
+ });
+
+ if (!empty($taxonomy_term_ids)) {
+ $term_queries[] = [
+ 'taxonomy' => $taxonomy,
+ 'field' => 'term_id',
+ 'terms' => array_values($taxonomy_term_ids),
+ 'operator' => 'IN'
+ ];
+ }
+ }
+
+ if (!empty($term_queries)) {
+ if (isset($args['tax_query'])) {
+ $args['tax_query'] = [
+ 'relation' => 'OR',
+ $args['tax_query'],
+ [
+ 'relation' => 'OR',
+ ...$term_queries
+ ]
+ ];
+ } else {
+ $args['tax_query'] = [
+ 'relation' => 'OR',
+ ...$term_queries
+ ];
+ }
+ }
+
+ return $args;
+ }
+
/**
* Gets allowed taxonomies for a particular content
* @param string $content
@@ -369,7 +455,20 @@
foreach ($posts as $ID => $post_data) {
if (Features::forContent($post_data['content'])->has('is_timeline') && array_key_exists('timeline', $post_data)) {
- $results[$ID] =$this->processTimelinePost($ID, $post_data);
+ // Handle timeline posts - ensure we have a valid integer ID
+ $parent_id = (int)$ID;
+
+ // Skip if ID is invalid (0, 'null', etc would become 0)
+ if ($parent_id === 0) {
+ error_log('Invalid timeline parent ID: ' . $ID);
+ $results[$ID] = [
+ 'success' => false,
+ 'message' => 'Invalid parent post ID for timeline'
+ ];
+ continue;
+ }
+
+ $results[$ID] = $this->processTimelinePost($parent_id, $post_data);
continue;
}
if (str_starts_with($ID, 'new')) {
--
Gitblit v1.10.0