Jake Vanderwerf
2026-01-25 b38f03c0e7218762d90fa5092696b127f24f36db
inc/rest/routes/FavouritesRoutes.php
@@ -2,8 +2,8 @@
namespace JVBase\rest\routes;
use JVBase\JVB;
use JVBase\managers\Cache;
use JVBase\rest\RestRouteManager;
use JVBase\managers\CacheManager;
use WP_REST_Request;
use WP_REST_Response;
use WP_Error;
@@ -16,16 +16,21 @@
class FavouritesRoutes extends RestRouteManager
{
    protected array $valid_types;
    protected int $user_id;
   protected Cache $listsCache;
   protected Cache $sharedListsCache;
   protected Cache $favouritesCache;
    public function __construct()
    {
        $this->cache_name = 'favourites';
        parent::__construct();
      $this->cache->connect('post')->connect('user')->connect('taxonomy');
      $this->listsCache = Cache::for('lists')->connect('favourites', true);
      $this->sharedListsCache = Cache::for('sharedLists')->connect('favourites', true);
      $this->favouritesCache = Cache::for('allFavourites')->connect('favourites', true);
        $this->valid_types = array_keys(array_merge(JVB_CONTENT, JVB_TAXONOMY));
        $this->user_id = get_current_user_id();
        $this->action = 'favourites-';
@@ -118,13 +123,14 @@
    {
      $args = $this->buildParams($request);
      if (!$args['user'] || $args['user'] === ''){
         $result = [
         return $this->addCacheHeaders(new WP_REST_Response([
            'success'   => false,
            'message'   => 'No user set'
         ];
         ]));
      }
      $key = $this->cache->generateKey($args);
      // Check HTTP cache headers for user-specific data
      $cache_check = $this->checkUserHeaders($request, $args['user'], 'favourites');
      $cache_check = $this->checkHeaders($request, $key);
      if ($cache_check) {
         return $cache_check;
      }
@@ -133,10 +139,9 @@
            $result = $this->getAllFavourites($args['user']);
      } else {
         $result = $this->cache->remember(
            $args,
            $this->cache->generateKey($args),
            function() use ($args) {
               $response = new WP_REST_Response($this->getFilteredFavourites($args));
               return $this->addCacheHeaders($response);
               return $this->getFilteredFavourites($args);
            }
         );
      }
@@ -237,7 +242,7 @@
        }
      $result = $this->cache->remember(
         'user_'.$user_id.'_all_favourites',
         $user_id,
         function() use ($user_id) {
            return $this->fetchAllFavourites($user_id);
         }
@@ -398,8 +403,15 @@
         ]);
      }
      $params = [
         'user'   => $user_id,
      ];
      if ($request->get_param('id')) {
         $params['list'] = sanitize_text_field($request->get_param('id'));
      }
      $key = $this->listsCache->generateKey($params);
      // Check HTTP cache headers
      $cache_check = $this->checkUserHeaders($request, $user_id, 'favourites_lists');
      $cache_check = $this->checkHeaders($request, $key);
      if ($cache_check) {
         return $cache_check;
      }
@@ -427,28 +439,21 @@
        if (!$this->checkUser($user_id)) {
            return [];
        }
        $key = sprintf(
            'user_%d_lists',
            $user_id
        );
        if ($include_shared) {
            $key = $key.'_shared';
        }
        $cache = $this->cache->get($key, 'favourites_lists');
        if ($cache) {
            return $cache;
        }
        global $wpdb;
        error_log('Attempting to get available lists..');
        $lists_table = $wpdb->prefix . BASE . 'favourites_lists';
        $items_table = $wpdb->prefix . BASE . 'favourites_list_items';
        $shares_table = $wpdb->prefix . BASE . 'favourites_list_shares';
      $cache = ($include_shared) ? $this->sharedListsCache : $this->listsCache;
      return $cache->remember(
         $user_id,
         function() use ($user_id, $include_shared) {
            global $wpdb;
            error_log('Attempting to get available lists..');
            $lists_table = $wpdb->prefix . BASE . 'favourites_lists';
            $items_table = $wpdb->prefix . BASE . 'favourites_list_items';
            $shares_table = $wpdb->prefix . BASE . 'favourites_list_shares';
        try {
            // Get owned lists
            $owned_query = $wpdb->prepare(
                "SELECT l.*,
            try {
               // Get owned lists
               $owned_query = $wpdb->prepare(
                  "SELECT l.*,
                COUNT(DISTINCT i.id) as item_count,
                TRUE as is_owner,
                FALSE as is_shared
@@ -457,16 +462,16 @@
            WHERE l.user_id = %d
            GROUP BY l.id
            ORDER BY l.created_at DESC",
                $user_id
            );
                  $user_id
               );
            $lists = $wpdb->get_results($owned_query);
            error_log('Lists result: '.print_r($lists, true));
               $lists = $wpdb->get_results($owned_query);
               error_log('Lists result: '.print_r($lists, true));
            // Add shared lists if requested
            if ($include_shared) {
                $shared_query = $wpdb->prepare(
                    "SELECT l.*,
               // Add shared lists if requested
               if ($include_shared) {
                  $shared_query = $wpdb->prepare(
                     "SELECT l.*,
                    u.display_name as owner_name,
                    COUNT(DISTINCT i.id) as item_count,
                    s.permission_type,
@@ -479,35 +484,33 @@
                WHERE s.user_id = %d
                GROUP BY l.id
                ORDER BY l.created_at DESC",
                    $user_id
                );
                     $user_id
                  );
                $shared_lists = $wpdb->get_results($shared_query);
                error_log('Shared lists: '.print_r($shared_lists, true));
                $lists = [
                    'owned' => $lists,
                    'shared'=> $shared_lists,
                ];
            }
                  $shared_lists = $wpdb->get_results($shared_query);
                  error_log('Shared lists: '.print_r($shared_lists, true));
                  $lists = [
                     'owned' => $lists,
                     'shared'=> $shared_lists,
                  ];
               }
               error_log('Lists: '.print_r($lists, true));
               return [
                  'success' => true,
                  'lists' => $lists
               ];
            } catch (Exception $e) {
               JVB()->error()->log(
                  'favourites',
                  'Error getting available lists: ' . $e->getMessage(),
                  ['user_id' => $user_id],
                  'error'
               );
            // Cache result
            $this->cache->set($key, ['success' => true, 'lists'=>$lists], 'favourites_lists');
            error_log('Lists: '.print_r($lists, true));
            return [
                'success' => true,
                'lists' => $lists
            ];
        } catch (Exception $e) {
            JVB()->error()->log(
                'favourites',
                'Error getting available lists: ' . $e->getMessage(),
                ['user_id' => $user_id],
                'error'
            );
            return [];
        }
               return [];
            }
         }
      );
    }
    /**
@@ -524,7 +527,7 @@
            $user_id,
            $list_id
        );
        $cache = $this->cache->get($key, 'favourites_lists');
        $cache = $this->listsCache->get($key);
        if ($cache) {
            return new WP_REST_Response($cache);
        }
@@ -649,7 +652,7 @@
            ]
        ];
        $this->cache->set($key, $response_data, 'favourites_lists');
        $this->listsCache->set($key, $response_data);
        return new WP_REST_Response($response_data);
    }
@@ -830,27 +833,30 @@
         ]);
      }
      $list_id = $request->get_param('list_id');
      if (!$list_id) {
         return $this->createErrorResponse(
            self::ERROR_MISSING_PARAMS,
            'List ID is required',
            400
         );
      }
      $args = [
         'user'   => $user_id,
         'list'   => sanitize_text_field($list_id),
      ];
      $key = $this->sharedListsCache->generateKey($args);
      // Check HTTP cache headers
      $cache_check = $this->checkUserHeaders($request, $user_id, 'favourites_shares');
      $cache_check = $this->checkHeaders($request, $key);
      if ($cache_check) {
         return $cache_check;
      }
      $list_id = $request->get_param('list_id');
        if (!$list_id) {
            return $this->createErrorResponse(
                self::ERROR_MISSING_PARAMS,
                'List ID is required',
                400
            );
        }
        $key = sprintf(
            'user_%d_shares_for_list_%d',
            $user_id,
            $list_id
        );
        $cache = $this->cache->get($key, 'favourites_list_shares');
        $cache = $this->sharedListsCache->get($key);
        if ($cache) {
            return new WP_REST_Response($cache);
        }
@@ -925,7 +931,7 @@
            ];
            // Cache the results
            $this->cache->set($key, $response_data, 'favourites_list_shares');
            $this->sharedListsCache->set($key, $response_data);
         $response = new WP_REST_Response($response_data);
         return $this->addCacheHeaders($response);
@@ -1265,7 +1271,7 @@
                'target_id' => $term_id,
                'date_added' => $item->date_added ?? current_time('mysql'),
                'notes' => $item->notes ?? '',
                'title' => $term->name,
                'title' => html_entity_decode($term->name),
                'url' => get_term_link($term)
            ];
@@ -1442,8 +1448,8 @@
            }
            error_log('Results: '.print_r($results, true));
            $this->cache->invalidate('favourite_counts_by_type_' . $user_id.'_all');
            $this->cache->invalidate('favourite_counts_by_type_' . $user_id.'_not_all');
            $this->cache->forget('favourite_counts_by_type_' . $user_id.'_all');
            $this->cache->forget('favourite_counts_by_type_' . $user_id.'_not_all');
            return [
                'success' => true,
                'result' => $results
@@ -1637,8 +1643,10 @@
            $this->removeRelatedNotifications($user_id, $type, $target_id);
            // Invalidate cache
            CacheManager::invalidateGroup($this->cache_name);
            CacheManager::invalidateGroup('favourites_lists');
         $this->cache->flush();
         $this->listsCache->flush();
         $this->sharedListsCache->flush();
         $this->favouritesCache->flush();
            return [
                'success' => true,
@@ -1722,9 +1730,9 @@
                }
                // Invalidate notification cache for this user
                if (method_exists(JVB()->notification(), 'clearNotificationCache')) {
                    JVB()->notification()->clearNotificationCache($owner_id);
                }
//                if (method_exists(JVB()->notification(), 'clearNotificationCache')) {
//                    JVB()->notification()->clearNotificationCache($owner_id);
//                }
            }
        } catch (Exception $e) {
            // Log but continue
@@ -2011,7 +2019,7 @@
            $wpdb->query('COMMIT');
            // Invalidate relevant caches
            CacheManager::invalidateGroup('favourites_lists');
         $this->listsCache->flush();
            return [
                'success' => true,
@@ -3302,47 +3310,47 @@
            switch ($operation->type) {
                case 'favourites_batch':
                    $response = $this->processBatches($user_id, $data);
                    CacheManager::invalidateGroup($this->cache_name);
               $this->cache->flush();
                    return $response;
                case 'favourite_notes':
                    $response =  $this->processNote($user_id, $data);
                    CacheManager::invalidateGroup($this->cache_name);
               $this->cache->flush();
                    return $response;
                case 'favourite_list_create':
                    $response = $this->processListCreate($user_id, $data);
                    CacheManager::invalidateGroup('favourites_lists');
               $this->listsCache->flush();
                    return $response;
                case 'favourite_list_update':
                    $response = $this->processUpdateList($user_id, $data);
                    CacheManager::invalidateGroup('favourites_lists');
               $this->listsCache->flush();
                    return $response;
                case 'favourite_list_delete':
                    $response = $this->processListDeletion($user_id, $data);
                    CacheManager::invalidateGroup('favourites_lists');
                    $this->listsCache->flush();
                    return $response;
                case 'favourite_list_add':
                    $response = $this->processAddToList($user_id, $data);
                    CacheManager::invalidateGroup('favourites_lists');
                    $this->listsCache->flush();
                    return $response;
                case 'favourite_list_remove':
                    $response = $this->removeFromList($user_id, $data);
                    CacheManager::invalidateGroup('favourites_lists');
                    $this->listsCache->flush();
                    return $response;
                case 'favourite_list_share':
                    $response = $this->shareList($user_id, $data);
                    CacheManager::invalidateGroup('favourites_lists_shares');
               $this->sharedListsCache->flush();
                    return $response;
                case 'favourite_list_unshare':
                    $response = $this->unshareList($user_id, $data);
                    CacheManager::invalidateGroup('favourites_lists_shares');
               $this->sharedListsCache->flush();
                    return $response;
                default: