Jake Vanderwerf
2025-11-23 d7dbe7fee362d587dfc334135d9581b6216a4295
inc/rest/routes/TermRoutes.php
@@ -5,6 +5,7 @@
use JVBase\rest\RestRouteManager;
use JVBase\managers\TaxonomyRelationships;
use JVBase\managers\UserTermsManager;
use JVBase\utility\Features;
use WP_REST_Request;
use WP_REST_Response;
use Exception;
@@ -180,9 +181,8 @@
    public function handleTermSelectionRequest(WP_REST_Request $request):WP_REST_Response
    {
      $data = $request->get_params();
      $taxonomy = jvbCheckBase($data['taxonomy']);
      $taxonomy = jvbCheckBase($data['taxonomy'])??'';
      error_log('Term Request Data for '.$taxonomy.': '.print_r($data, true));
      // Check HTTP cache headers
      $cache_check = $this->checkHeaders($request, $taxonomy);
      if ($cache_check) {
@@ -190,6 +190,11 @@
         return $cache_check;
      }
      // Handle batch request (multiple taxonomies)
      if (str_contains($taxonomy, ',')) {
         return $this->handleBatchTermRequest($taxonomy, $data, $request);
      }
      if (array_key_exists('termIDs', $data)) {
         $args = [
            'taxonomy'  => $taxonomy,
@@ -223,9 +228,10 @@
        $taxonomy = BASE.$request->get_param('taxonomy');
        $search = $request->get_param('search');
        $parent = (int)$request->get_param('parent');
        $page = max(1, (int)$request->get_param('page'));
        $per_page = max(20, (int)$request->get_param('per_page'));
      $parent = (int)$data['parent']??0;
      $page = max(1, (int)($data['page']??1));
      $per_page = 25;
        if (!taxonomy_exists($taxonomy)) {
            return new WP_REST_Response([
@@ -371,9 +377,9 @@
        $key = $this->cache->generateKey($args);
        $cache = $this->cache->get($key);
      $cache = false;
        if ($cache) {
            $response = new WP_ReST_Response($cache);
            $response = new WP_REST_Response($cache);
         return $this->addCacheHeaders($response);
        }
@@ -406,6 +412,45 @@
      return $this->addCacheHeaders($response);
    }
   protected function handleBatchTermRequest(string $taxonomy, array $data, WP_REST_Request $request):WP_REST_Response
   {
      $taxonomies = array_map('trim', explode(',', $taxonomy));
      $all_terms = [];
      $parent = (int)$data['parent']??0;
      $page = max(1, (int)($data['page']??1));
      $per_page = 25;
      $mainArgs = [
         'hide_empty'=> false,
         'parent' => $parent,
         'number' => $per_page,
         'orderby'   => 'name',
         'offset' => ($page -1) * $per_page,
      ];
      foreach ($taxonomies as $taxonomy) {
         if (!taxonomy_exists(BASE.$taxonomy)) {
            continue;
         }
         $args = $mainArgs;
         $args['taxonomy'] = BASE.$taxonomy;
         $all_terms = array_merge($all_terms, $this->formatTerms($args, $taxonomy));
      }
      $response = [
         'items'  => $all_terms,
         'pagination'=> [
            'page' => $page,
            'per_page'=> $per_page,
            'has_more' => true,
         ]
      ];
      $response = new WP_REST_Response($response);
      return $this->addCacheHeaders($response);
   }
    /**
     * @param array $args
     * @param string $taxonomy
@@ -414,17 +459,50 @@
     */
    protected function formatTerms(array $args, string $taxonomy):array
    {
      return $this->cache->remember(
         $this->cache->generateKey($args),
         function() use ($args, $taxonomy) {
        $terms = get_terms($args);
        if (is_wp_error($terms)) {
            return [];
        }
        $formatted_terms = [];
        foreach ($terms as $term) {
            // Check for children explicitly
               $formatted_terms[] = $this->formatSingleTerm($term, $taxonomy, true);
            }
            return $formatted_terms;
         }
      );
   }
   /**
    * Format a single term with caching
    *
    * @param object $term WP_Term object
    * @param string $taxonomy Full taxonomy name
    *
    * @return array Formatted term data
    */
   protected function formatSingleTerm(object $term, string $taxonomy): array
   {
      $cache_key = "{$term->term_id}_{$taxonomy}";
      return $this->cache->remember($cache_key, function() use ($term, $taxonomy) {
         $data = [
            'id' => $term->term_id,
            'name' => $term->name,
            'slug' => $term->slug,
            'parent' => $term->parent,
            'path' => $this->getTermPath($term->term_id, $term->name, $taxonomy),
            'taxonomy' => jvbNoBase($term->taxonomy),
            'count' => $term->count,
         ];
            $children_args = [
                'taxonomy' => $taxonomy,
                'parent' => $term->term_id,
@@ -432,21 +510,11 @@
                'hide_empty' => false
            ];
            $count = wp_count_terms($children_args);
            $has_children = !is_wp_error($count) && $count > 0;
         $data['hasChildren'] = !is_wp_error($count) && $count > 0;
            $formatted_terms[] = [
                'id' => $term->term_id,
                'name' => $term->name,
            'slug'   => $term->slug,
                'parent' => $term->parent,
                'path' => $this->getTermPath($term->term_id, $term->name, $taxonomy),
                'hasChildren' => $has_children,
            'taxonomy'  => $term->taxonomy,
            'count'     => $term->count,
            ];
        }
        return $formatted_terms;
         return $data;
      });
    }
    /**
@@ -499,14 +567,8 @@
        $formatted_terms = [];
        foreach ($terms as $term) {
            $formatted_terms[$term->term_id] = [
                'id'            => $term->term_id,
                'name'          => $term->name,
                'parent'        => $term->parent,
                'path'          => $this->getTermPath($term->term_id, $term->name, $taxonomy),
                'hasChildren'   => (bool)$term->has_children,
                'count'         => (int)$term->count
            ];
         // Search results show path, so includeChildren = false for performance
         $formatted_terms[] = $this->formatSingleTerm($term, $taxonomy, false);
        }
        // Calculate pagination info
@@ -699,13 +761,10 @@
            $is_hierarchical = is_taxonomy_hierarchical($taxonomy);
            foreach ($terms as $term) {
                $formatted_terms[$term->term_id] = [
                    'id' => $term->term_id,
                    'name' => $term->name,
                    'count' => $term->count,
                    'path' => $this->getTermPath($term->term_id, $term->name, $taxonomy),
                    'relationship_strength' => $term->relationship_count ?? 0
                ];
            $formatted = $this->formatSingleTerm($term, $taxonomy, false);
            // Add relationship strength which is unique to this method
            $formatted['relationship_strength'] = $term->relationship_count ?? 0;
            $formatted_terms[] = $formatted;
            }
            // Build response
@@ -792,13 +851,7 @@
            // Format terms
            $formatted_terms = [];
            foreach ($terms as $term) {
                $formatted_terms[$term->term_id] = [
                    'id' => $term->term_id,
                    'name' => $term->name,
                    'count' => $term->count,
                    'parent' => $term->parent,
                    'path' => $this->getTermPath($term->term_id, $term->name, $taxonomy)
                ];
            $formatted_terms[] = $this->formatSingleTerm($term, $taxonomy, false);
            }
            // Get total for pagination
@@ -842,13 +895,15 @@
        $name = sanitize_text_field($request->get_param('name'));
        $parent = (int)$request->get_param('parent') ?: 0;
        try {
            // Check if term already exists
            $existing = term_exists($name, jvbCheckBase($taxonomy), $parent);
            if ($existing) {
                $term = get_term($existing['term_id'], jvbCheckBase($taxonomy));
                $term = get_term($existing['term_id'], jvbCheckBase($taxonomy));
            error_log('Existing Term: '.print_r($term, true));
                return new WP_REST_Response([
                    'success' => false,
                    'message' => 'Term already exists',
@@ -861,7 +916,8 @@
            }
         if (jvbSiteHasTermApproval()) {
         if (Features::forMembership()->has('term_approval')) {
            error_log('Term Approval required');
            // Get approval routes instance
            $approval_routes = JVB()->routes('approvals');
            // Create approval request
@@ -885,13 +941,15 @@
               ]
            ];
         } else {
            error_log('Creating new Term: ');
            $termID = wp_insert_term(
               $name,
               jvbCheckBase($taxonomy),
               [
                  'parent' => absint($parent??0)
                  'parent' => absint($parent)
               ]
            );
            error_log('Result: '.print_r($termID, true));
            if (is_wp_error($termID)) {
               throw new Exception('Failed to create new term');