Jake Vanderwerf
2026-02-10 bf69b2c2daeb2d5c1f9b1b3dfe99bfb62a739a9a
inc/managers/UserTermsManager.php
@@ -1,8 +1,6 @@
<?php
namespace JVBase\managers;
use JVBase\JVB;
use JVBase\managers\CacheManager;
use WP_Post;
use WP_Error;
use Exception;
@@ -13,7 +11,7 @@
class UserTermsManager
{
    private string $table_name;
    private CacheManager $cache;
    private Cache $cache;
    private string $cacheGroup  = 'user_terms_';
    private int $ttl = DAY_IN_SECONDS; // 1 day default
   protected \wpdb $wpdb;
@@ -23,8 +21,6 @@
        global $wpdb;
      $this->wpdb = $wpdb;
        $this->table_name = $this->wpdb->prefix . BASE . 'user_term_index';
        // Get cache manager instance
        $this->cache = new CacheManager($this->cacheGroup, $this->ttl);
        // Register hooks
        add_action('save_post', [$this, 'updatePostUserTerms'], 10, 3);
@@ -43,15 +39,8 @@
     */
    public function clearUserCache(int $user_id, string|null $taxonomy = null):void
    {
        if ($taxonomy) {
            // Clear specific taxonomy cache
            $pattern = "user_{$user_id}_" . str_replace(BASE, '', $taxonomy);
            $this->cache->clearPattern($pattern);
        } else {
            // Clear all user term caches
            $pattern = "user_{$user_id}_";
            $this->cache->clearPattern($pattern);
        }
      $cache = Cache::for($user_id.'_term_relationships', DAY_IN_SECONDS)->connect('post', true)->connect('taxonomy', true);
      $cache->flush();
    }
    // Update term usage when a post is saved
@@ -69,6 +58,10 @@
        if (wp_is_post_autosave($post_id) || wp_is_post_revision($post_id)) {
            return;
        }
      // SAFETY: Skip attachments and other non-content post types
      if (in_array($post->post_type, jvbIgnoredPostTypes())) {
         return;
      }
        // Skip non-custom post types
        $post_type = get_post_type($post);
@@ -414,12 +407,13 @@
        $this->wpdb->query("TRUNCATE TABLE {$this->table_name}");
        // Get all users with posts
        $users = $this->wpdb->get_col("
            SELECT DISTINCT post_author
            FROM {$this->wpdb->posts}
            WHERE post_status = 'publish'
            AND post_type LIKE '" . BASE . "%'
        ");
      $users = $this->wpdb->get_col($this->wpdb->prepare(
         "SELECT DISTINCT post_author
         FROM {$this->wpdb->posts}
         WHERE post_status = 'publish'
         AND post_type LIKE %s",
         $this->wpdb->esc_like(BASE) . '%'
      ));
        JVB()->queue()->queueOperation(
            'rebuild_user_term_index',
@@ -495,14 +489,14 @@
                $this->clearUserCache($user_id);
                // Get all the user's published posts
                $posts = $this->wpdb->get_col($this->wpdb->prepare(
                    "SELECT ID FROM {$this->wpdb->posts}
            WHERE post_author = %d
            AND post_status = 'publish'
            AND post_type LIKE '%s'",
                    $user_id,
               BASE
                ));
            $posts = $this->wpdb->get_col($this->wpdb->prepare(
               "SELECT ID FROM {$this->wpdb->posts}
               WHERE post_author = %d
               AND post_status = 'publish'
               AND post_type LIKE %s",
               $user_id,
               $this->wpdb->esc_like(BASE) . '%'
            ));
                $processed_terms = 0;
@@ -592,17 +586,17 @@
    private function fetchUserTerms(int $user_id, string $taxonomy, array $args):array
    {
        $taxonomy = jvbCheckBase($taxonomy);
        $key = $this->cache->generateKey(array_merge(
      $cache = Cache::for($user_id.'_term_relationships', DAY_IN_SECONDS)->connect('post', true)->connect('taxonomy', true);
        $key = $cache->generateKey(array_merge(
            [
                'user'      => $user_id,
                'taxonomy'  => $taxonomy,
            ],
            $args
        ));
        if (!$args['skip_cache']) {
            $cache = $this->cache->get($key);
            if ($cache) {
                return $cache;
            $cached = $cache->get($key);
            if ($cached) {
                return $cached;
            }
        }
@@ -654,7 +648,7 @@
            $this->wpdb->prepare($query, $query_args),
            ARRAY_A
        );
        $this->cache->set($key, $results);
        $cache->set($key, $results);
        return $results;
    }
@@ -682,59 +676,4 @@
        }, $terms);
    }
    /**
     * @param int $user_id
     *
     * @return bool
     */
    public function warmCache(int $user_id):bool
    {
        // Get all taxonomies
        $taxonomies = getTaxonomies(['_builtin' => false], 'names');
        foreach ($taxonomies as $taxonomy) {
            if (str_starts_with($taxonomy, BASE)) {
                // Pre-cache the most common queries
                $common_args = [
                    // Most frequently used terms
                    [
                        'orderby' => 'count',
                        'order' => 'DESC',
                        'limit' => 20,
                        'include_parents' => true
                    ],
                    // Recently used terms
                    [
                        'orderby' => 'last_used',
                        'order' => 'DESC',
                        'limit' => 20,
                        'include_parents' => true
                    ],
                    // Alphabetical list
                    [
                        'orderby' => 'name',
                        'order' => 'ASC',
                        'limit' => 0,
                        'include_parents' => true
                    ],
                    // Direct terms only (no parents)
                    [
                        'orderby' => 'count',
                        'order' => 'DESC',
                        'limit' => 0,
                        'only_direct' => true
                    ]
                ];
                foreach ($common_args as $args) {
                    // Force skip_cache to ensure we get fresh data
                    $args['skip_cache'] = true;
                    // Warm the cache by executing the query
                    $this->getUserTerms($user_id, $taxonomy, $args);
                }
            }
        }
        return true;
    }
}