From 772462eeca3002a1d52508aeba485aab2b4742ad Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Tue, 03 Mar 2026 19:06:19 +0000
Subject: [PATCH] =MAJOR OVERHAUL. Likely should have made a new branch ages ago. Key changes: Registrar.php is the base for custom post types, taxonomies, and user roles. Replaces JVB_CONTENT, JVB_TAXONOMY, and JVB_USER constants, eliminates most of Features.php (except for JVB_SITE, JVB_MEMBERSHIP), and has built in sanitizing and validation via sub-classes. Also started a major overhaul of the Schema output. Created a shit ton of property traits and classes to help sanitize and ensure proper data for different schema types. Still a bunch to do, but better to be starting committing changes here on this other branch.
---
inc/managers/NotificationManager.php | 246 ++++++++++++++++++++++--------------------------
1 files changed, 112 insertions(+), 134 deletions(-)
diff --git a/inc/managers/NotificationManager.php b/inc/managers/NotificationManager.php
index 5656303..2aaa4cf 100644
--- a/inc/managers/NotificationManager.php
+++ b/inc/managers/NotificationManager.php
@@ -2,6 +2,7 @@
namespace JVBase\managers;
use JVBase\JVB;
+use JVBase\registrar\Registrar;
use WP_Error;
use Exception;
use WP_Post;
@@ -20,7 +21,11 @@
*/
class NotificationManager
{
- protected object $cache;
+ protected Cache $userCache; //the individual notifications
+ protected Cache $contentCache; //the 'shared' notifications on new content that has been created
+ protected Cache $artistsCache;
+ protected Cache $favouritesCache;
+ protected Cache $followerCache;
protected string $campaign;
protected string $table = BASE.'notifications';
protected string $contentTable = BASE.'notifications_content';
@@ -139,7 +144,11 @@
*/
public function __construct()
{
- $this->cache = CacheManager::for('notifications', WEEK_IN_SECONDS);
+ $this->userCache = Cache::for('userNotifications', WEEK_IN_SECONDS);
+ $this->contentCache = Cache::for('contentNotifications', WEEK_IN_SECONDS)->connect('post', true)->connect('taxonomy', true);
+ $this->artistsCache = Cache::for('artist', WEEK_IN_SECONDS)->connect('post');
+ $this->favouritesCache = Cache::for('favouritedUsers', WEEK_IN_SECONDS)->connect('favourites');
+ $this->followerCache = Cache::for('totalFollowers', WEEK_IN_SECONDS)->connect('favourites');
// Add filter for bulk operation handling
add_filter(BASE . 'handle_bulk_operation', [ $this, 'processOperation' ], 10, 3);
@@ -364,7 +373,7 @@
*/
public function notifyVerifiedArtists(string $type, int|null $action_user_id = null, string $message = '', int|null $target_id = null, string|null $target_type = null, array|null $context = null):bool|WP_Error
{
- $artists = $this->getVerifiedArtists();
+ $artists = $this->getVerified('artist');
return $this->addNotification($artists, $type, $action_user_id, $message, $target_id, $target_type, $context);
}
/**
@@ -381,7 +390,7 @@
*/
public function notifyVerifiedPartners(string $type, int|null $action_user_id = null, string $message = '', int|null $target_id = null, string|null $target_type = null, array|null $context = null):bool|WP_Error
{
- $artists = $this->getVerifiedPartners();
+ $artists = $this->getVerified('partner');
return $this->addNotification($artists, $type, $action_user_id, $message, $target_id, $target_type, $context);
}
/**
@@ -398,7 +407,7 @@
*/
public function notifyEnthusiasts(string $type, int|null $action_user_id = null, string $message = '', int|null $target_id = null, string|null $target_type = null, array|null $context = null):bool|WP_Error
{
- $artists = $this->getEnthusiasts();
+ $artists = $this->getUserIDs('enthusiast');
return $this->addNotification($artists, $type, $action_user_id, $message, $target_id, $target_type, $context);
}
/**
@@ -415,7 +424,7 @@
*/
public function notifyEveryone(string $type, int|null $action_user_id = null, string $message = '', int|null $target_id = null, string|null $target_type = null, array|null $context = null):bool|WP_Error
{
- $artists = $this->getEveryone();
+ $artists = $this->getUserIDs(Registrar::getRegistered('user'));
return $this->addNotification($artists, $type, $action_user_id, $message, $target_id, $target_type, $context);
}
@@ -445,7 +454,7 @@
}
// Check if this is a relevant content type
- $content_types = jvbBasedFeedContent();
+ $content_types = array_map(function($type) {return jvbCheckBase($type->getSlug()); }, Registrar::getFeatured('show_feed', 'post'));
if (!in_array($post->post_type, $content_types)) {
return;
}
@@ -1100,7 +1109,7 @@
}
$content = '';
- $cache = CacheManager::for('digest_content', HOUR_IN_SECONDS * 6); // Cache for 6 hours
+ $cache = Cache::for('digest_content', HOUR_IN_SECONDS * 6); // Cache for 6 hours
// Group updates by artist
$updates_by_artist = [];
@@ -1519,19 +1528,16 @@
protected function getArtistData(int $user_id):array|false
{
// Try to get from cache
- $cache_key = "artist_data_{$user_id}";
- $cached = $this->cache->get($cache_key);
+ $artist_id = get_user_meta($user_id, BASE . 'link', true);
+ if (!$artist_id || $artist_id === '') {
+ return false;
+ }
+ $cached = $this->artistsCache->get($artist_id);
if ($cached !== false) {
return $cached;
}
- // Get artist post ID from user meta
- $artist_id = get_user_meta($user_id, BASE . 'link', true);
- if (!$artist_id) {
- return false;
- }
-
// Get basic artist data
$artist_post = get_post($artist_id);
if (!$artist_post) {
@@ -1548,7 +1554,7 @@
];
// Cache the result
- $this->cache->set($cache_key, $data, null,'artists');
+ $this->artistsCache->set($artist_id, $data);
return $data;
}
@@ -1560,19 +1566,25 @@
*/
protected function getFollowedArtists(int $user_id):array
{
- global $wpdb;
- $favourites_table = $wpdb->prefix . BASE . 'favourites';
+ return $this->favouritesCache->remember(
+ $user_id,
+ function() use ($user_id) {
+ global $wpdb;
+ $favourites_table = $wpdb->prefix . BASE . 'favourites';
- // Get artists this user has favourited
- return $wpdb->get_col($wpdb->prepare(
- "SELECT f.target_id
- FROM {$favourites_table} f
- JOIN {$wpdb->posts} p ON f.target_id = p.ID
- WHERE f.user_id = %d
- AND f.type = 'artist'
- AND p.post_status = 'publish'",
- $user_id
- ));
+ // Get artists this user has favourited
+ return $wpdb->get_col($wpdb->prepare(
+ "SELECT f.target_id
+ FROM {$favourites_table} f
+ JOIN {$wpdb->posts} p ON f.target_id = p.ID
+ WHERE f.user_id = %d
+ AND f.type = 'artist'
+ AND p.post_status = 'publish'",
+ $user_id
+ ));
+ }
+ );
+
}
/**
@@ -1582,15 +1594,21 @@
*/
protected function getFollowerCount(int $artist_id):int
{
- global $wpdb;
- $favourites_table = $wpdb->prefix . BASE . 'favourites';
+ return $this->followerCache->remember(
+ $artist_id,
+ function() use ($artist_id) {
+ global $wpdb;
+ $favourites_table = $wpdb->prefix . BASE . 'favourites';
- return $wpdb->get_var($wpdb->prepare(
- "SELECT COUNT(DISTINCT user_id)
- FROM {$favourites_table}
- WHERE target_id = %d AND type = 'artist'",
- $artist_id
- ));
+ return $wpdb->get_var($wpdb->prepare(
+ "SELECT COUNT(DISTINCT user_id)
+ FROM {$favourites_table}
+ WHERE target_id = %d AND type = 'artist'",
+ $artist_id
+ ));
+ }
+ );
+
}
/**
@@ -1598,27 +1616,11 @@
*
* @return string
*/
- protected function pluralize(string $word):string
+ protected function pluralize(string $content):string
{
- $irregular = [
- 'tattoo' => 'tattoos',
- 'piercing' => 'piercings',
- 'artwork' => 'artwork',
- 'news' => 'news',
- 'offer' => 'offers',
- 'event' => 'events'
- ];
-
- if (isset($irregular[$word])) {
- return $irregular[$word];
- }
-
- // Simple pluralization rules
- if (str_ends_with($word, 'y')) {
- return substr($word, 0, -1) . 'ies';
- }
-
- return $word . 's';
+ $registrar = Registrar::getInstance($content);
+ return ($registrar) ? $registrar->getPlural()
+ : str_replace('_', ' ', $content.'s');
}
/**
@@ -1628,9 +1630,8 @@
*/
protected function clearNotificationCache(int $user_id):void
{
-
- $this->cache->delete("user_{$user_id}_notifications_", 'notifications_' . $user_id);
- $this->cache->delete("user_{$user_id}_content_notifications_", 'notifications_' . $user_id);
+ $this->userCache->forget($user_id);
+ $this->contentCache->forget($user_id);
}
/**
@@ -1697,78 +1698,56 @@
/**
* @return array
*/
- protected function getVerifiedArtists():array
+ protected function getVerified(string|array $userRoles):array
{
- $artists = $this->cache->get('verified_artists');
- if ($artists) {
- return $artists;
- }
+ $userRoles = $this->checkRoles($userRoles);
- $artists = get_users([
- 'role' => BASE.'artist',
- 'capability' => 'skip_moderation',
- 'fields' => 'ID'
- ]);
-
- $this->cache->set('verified_artists', $artists);
- return $artists;
+ if (empty($userRoles)) {
+ return [];
+ }
+ $cache = Cache::for('verifiedUsers', DAY_IN_SECONDS)->connect('user',true);
+ return $cache->remember(
+ 'verified',
+ function() use ($userRoles) {
+ return get_users([
+ 'role' => $userRoles,
+ 'capability' => 'skip_moderation',
+ 'fields' => 'ID'
+ ]);
+ }
+ );
}
- /**
- * @return array
- */
- protected function getVerifiedPartners():array
- {
- $partners = $this->cache->get('verified_partners');
- if ($partners) {
- return $partners;
- }
+ protected function getUserIDs(array|string $roles):array
+ {
+ $roles = $this->checkRoles($roles);
+ if (empty($roles)) {
+ return [];
+ }
+ $cache = Cache::for('everyone', DAY_IN_SECONDS)->connect('user', true);
+ return $cache->remember(
+ $cache->generateKey($roles),
+ function() use ($roles) {
+ return get_users([
+ 'role' => $roles,
+ 'fields' => 'ID'
+ ]);
+ }
+ );
+ }
- $partners = get_users([
- 'role' => BASE.'partner',
- 'capability' => 'skip_moderation',
- 'fields' => 'ID'
- ]);
+ protected function checkRoles(string|array $roles):array
+ {
+ if (!is_array($roles)) {
+ $roles = explode(',',$roles);
+ }
- $this->cache->set('verified_partners', $partners);
- return $partners;
- }
-
- /**
- * @return array
- */
- protected function getEnthusiasts():array
- {
- $enthusiasts = $this->cache->get('enthusiasts');
- if ($enthusiasts) {
- return $enthusiasts;
- }
-
- $enthusiasts = get_users([
- 'role' => BASE.'enthusiast',
- 'fields' => 'ID'
- ]);
-
- $this->cache->set('enthusiasts', $enthusiasts);
- return $enthusiasts;
- }
-
- /**
- * @return array
- */
- protected function getEveryone():array
- {
- $users = $this->cache->get('users');
- if ($users) {
- return $users;
- }
- $users = get_users([
- 'role__in' => [BASE.'artist', BASE.'enthusiast', BASE.'partner'],
- 'fields' => 'ID'
- ]);
- $this->cache->set('users', $users);
- return $users;
- }
+ return array_map(function ($r) {
+ return jvbCheckBase(trim($r));
+ }, array_filter($roles, function ($r) {
+ return Registrar::getInstance(trim($r))!== false;
+ }));
+ }
/**
* @param int $userID
@@ -1777,13 +1756,12 @@
*/
protected function checkUser(int $userID):bool
{
- $checked = $this->cache->get($userID, 'checked_users');
- if ($checked) {
- return $checked;
- }
- $test = (bool)get_userdata($userID);
-
- $this->cache->set($userID, $test, null, 'checked_users');
- return $test;
+ $cache = Cache::for('checked_users', DAY_IN_SECONDS)->connect('user', true);
+ return $cache->remember(
+ $userID,
+ function() use ($userID) {
+ return (bool)get_userdata($userID)?:null;
+ }
+ );
}
}
--
Gitblit v1.10.0