| | |
| | | { |
| | | $this->cache_name = 'user_content_'.get_current_user_id(); |
| | | parent::__construct(); |
| | | |
| | | $this->cache->clear(); |
| | | $this->action = 'dash-'; |
| | | $this->operation_type = 'content_update'; |
| | | add_filter(BASE.'handle_bulk_operation', [$this, 'processOperation'], 10, 3); |
| | |
| | | if (Features::forContent($post_type)->has('is_calendar')) { |
| | | $args = $this->applyCalendarFilters($args, $params); |
| | | } |
| | | $taxonomies = array_filter($params, function($param) { |
| | | return str_starts_with($param, 'tax_'); |
| | | }, ARRAY_FILTER_USE_KEY); |
| | | if (!empty($taxonomies)) { |
| | | $params['taxonomies'] = []; |
| | | foreach ($taxonomies as $taxonomy => $terms) { |
| | | $taxonomy = str_replace('tax_', '', $taxonomy); |
| | | $params['taxonomies'][$taxonomy] = $terms; |
| | | } |
| | | } |
| | | 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']); |
| | | } |
| | | |
| | |
| | | |
| | | |
| | | $cache = $this->cache->get($key); |
| | | $cache = false; |
| | | if ($cache) { |
| | | $response = new WP_REST_Response($cache); |
| | | 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); |
| | |
| | | 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 |
| | |
| | | |
| | | 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')) { |
| | |
| | | return $images; |
| | | } |
| | | |
| | | protected function formatTimeline(WP_Post $post):array |
| | | public function formatTimeline(WP_Post $post):array |
| | | { |
| | | $item = $this->prepareItem($post, true, false); |
| | | //Step 1: Get the fields that apply to all posts |