From f0645f805ecdd19cf5ed9842f9e6b69a86dbcdeb Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Thu, 27 Aug 2026 15:28:09 +0000
Subject: [PATCH] =Notifications and routes minor cleanup. needs more work

---
 inc/blocks/FAQBlock.php                      |    1 
 inc/rest/Rest.php                            |   10 +
 inc/managers/Notifications/Notifications.php |   60 ++++++++--
 inc/managers/NotificationManager.php         |    4 
 inc/rest/routes/NotificationsRoutes.php      |  263 +++++--------------------------------------
 5 files changed, 94 insertions(+), 244 deletions(-)

diff --git a/inc/blocks/FAQBlock.php b/inc/blocks/FAQBlock.php
index c43133c..f52cf42 100644
--- a/inc/blocks/FAQBlock.php
+++ b/inc/blocks/FAQBlock.php
@@ -2,6 +2,7 @@
 namespace JVBase\blocks;
 
 use JVBase\managers\Cache;
+use JVBase\managers\DirectoryManager;
 use JVBase\registrar\Registrar;
 use WP_Block;
 use WP_Query;
diff --git a/inc/managers/NotificationManager.php b/inc/managers/NotificationManager.php
index 9b12b4f..b19dac9 100644
--- a/inc/managers/NotificationManager.php
+++ b/inc/managers/NotificationManager.php
@@ -74,6 +74,10 @@
    {
 	   return $this->notifications->getUserNotifications($user_id, $args);
    }
+   public function countUserNotifications(int $user_id, array $args = []):int
+   {
+	   return $this->notifications->countUserNotifications($user_id, $args);
+   }
 
    public function markRead(int $userID, int|array $notification_id):bool
    {
diff --git a/inc/managers/Notifications/Notifications.php b/inc/managers/Notifications/Notifications.php
index 61ee88c..aa8f576 100644
--- a/inc/managers/Notifications/Notifications.php
+++ b/inc/managers/Notifications/Notifications.php
@@ -315,24 +315,60 @@
 		return true;
 	}
 
-	public function getUserNotifications(int $user_id, array $where = []):array
+	protected function buildArgs(array $args):array
 	{
-		$gotWhere = $where;
-		$allowedKeys = ['from_user','target_id', 'target_type','type','status','priority','action_taken','created_at','read_at','actioned_at','updated_at'];
-		$where = array_filter($gotWhere, function($key) use ($allowedKeys) {
-			return in_array($key, $allowedKeys);
+		$allowed = $this->notifications->getColumnKeys();
+		$where = array_filter($args, function($key) use ($allowed) {
+			return in_array($key, $allowed);
 		}, ARRAY_FILTER_USE_KEY);
-		$notAllowed = array_diff($gotWhere, $allowedKeys);
-		if (!empty($notAllowed)){
-			error_log('[Notifications]::getUserNotifications Invalid where arguments, removed from request: '.print_r($notAllowed, true));
+
+		if ($where['type'] === 'all') {
+			unset($where['type']);
 		}
 
-		return $this->notifications->getMany(array_merge([
-			'for_user'	=> $user_id,
-			'status'	=> 'unread',	//default to unread, but the merge will override if different
-		], $where));
+
+		$args['page'] = max(1, intval($args['page']??1));
+		$order = wp_parse_args($args, [
+			'orderby'	=> 'created_at',
+			'order'		=> 'DESC',
+			'per_page'	=> 20,
+			'page'		=> 1,
+		]);
+
+		$args = array_merge([
+			'where'	=> $where,
+		],$order);
+
+		return $args;
 	}
 
+	public function getUserNotifications(int $user_id, array $args = []):array
+	{
+		$args = $this->buildArgs($args);
+
+		$args['where']['for_user'] = $user_id;
+		if (!array_key_exists('status', $args['where'])) {
+			$args['where']['status'] = 'unread';
+		}
+
+
+		return $this->notifications->getMany($args, false);
+	}
+
+	public function countUserNotifications(int $user_id, array $args = []):int
+	{
+		$args = $this->buildArgs($args);
+
+		$args['where']['for_user'] = $user_id;
+		if (!array_key_exists('status', $args['where'])) {
+			$args['where']['status'] = 'unread';
+		}
+
+		return $this->notifications->count($args);
+	}
+
+
+
 	public function markRead(int $userID, int|array $notification_id):bool
 	{
 		if (is_int($notification_id)) {
diff --git a/inc/rest/Rest.php b/inc/rest/Rest.php
index 4238e96..9cc7e14 100644
--- a/inc/rest/Rest.php
+++ b/inc/rest/Rest.php
@@ -491,6 +491,16 @@
 		return $cache->remember($userId, fn() => (bool) get_userdata($userId));
 	}
 
+	protected function checkArray(string $value, array $search, bool $lowercase = true):string|false
+	{
+		if ($lowercase) {
+			$value = strtolower($value);
+		}
+
+		return in_array($value, $search) ? $value : false;
+
+	}
+
 	/**
 	 * Check if term exists (cached)
 	 */
diff --git a/inc/rest/routes/NotificationsRoutes.php b/inc/rest/routes/NotificationsRoutes.php
index fd04460..0e9bd82 100644
--- a/inc/rest/routes/NotificationsRoutes.php
+++ b/inc/rest/routes/NotificationsRoutes.php
@@ -1,9 +1,12 @@
 <?php
 namespace JVBase\rest\routes;
 
+use JVBase\base\Site;
 use JVBase\Instance;
+use JVBase\managers\Approvals;
 use JVBase\managers\Cache;
 use JVBase\managers\CustomTable;
+use JVBase\managers\NotificationManager;
 use JVBase\registrar\Registrar;
 use JVBase\rest\Rest;
 use JVBase\rest\Route;
@@ -109,10 +112,7 @@
 		$this->cacheName = 'notifications';
 		$this->cacheTtl = HOUR_IN_SECONDS;
 		parent::__construct();
-		$this->cache = Cache::for($this->cacheName, 'user', $this->cacheTtl);
 
-		$this->notifications = CustomTable::for('notifications');
-		$this->metrics = CustomTable::for('notification_metrics');
 
 		// Build complete type map
 		$allTypes = [];
@@ -218,38 +218,9 @@
 		if (!$user_id) {
 			return $this->unauthorized();
 		}
-		$type = sanitize_text_field($request->get_param('type') ?? '');
-		$status = sanitize_text_field($request->get_param('status') ?? '');
-		$limit = absint($request->get_param('limit'));
-		$offset = absint($request->get_param('offset'));
+		$args = $this->buildParams($request);
 
-		$cacheKey = compact('user_id', 'type', 'status', 'limit', 'offset');
-
-		$result = $this->cache->remember($cacheKey, function() use ($user_id, $type, $status, $limit, $offset) {
-			// Build where conditions
-			$where = ['owner_id' => $user_id];
-			if ($type) $where['type'] = $type;
-			if ($status) $where['status'] = $status;
-
-			$items = $this->notifications
-				->where($where)
-				->orderBy('created_at', 'DESC')
-				->limit($limit, $offset)
-				->getResults();
-
-			$total = $this->notifications->where($where)->countResults();
-
-			// Format notifications
-			$formatted = array_map([$this, 'formatNotification'], $items);
-
-			return [
-				'items' => $formatted,
-				'total' => $total,
-				'has_more' => ($offset + $limit) < $total
-			];
-		});
-
-		return $this->success($result);
+		return $this->success($this->manager->getUserNotifications($user_id, $args));
 	}
 
 	/**
@@ -261,16 +232,10 @@
 		if (!$user_id) {
 			return $this->unauthorized();
 		}
-		$type = sanitize_text_field($request->get_param('type') ?? '');
 
-		$cacheKey = compact('user_id', 'type');
-
-		$count = $this->cache->remember($cacheKey, function() use ($user_id, $type) {
-			$where = ['owner_id' => $user_id, 'status' => 'unread'];
-			if ($type) $where['type'] = $type;
-
-			return $this->notifications->where($where)->countResults();
-		});
+		$args = $this->buildParams($request);
+		$args['status'] = 'unread';
+		$count = $this->manager->countUserNotifications($user_id, $args);
 
 		return $this->success(['count' => $count]);
 	}
@@ -394,192 +359,8 @@
 		});
 	}
 
-	/**
-	 * Get regular notifications from the notifications table
-	 */
-	protected function getRegularNotifications(int $user_id, array $params): array
-	{
-		$cacheKey = compact('user_id', 'params');
 
-		return $this->cache->remember($cacheKey, function() use ($user_id, $params) {
-			$status = $params['status'];
-			$type = $params['type'];
-			$limit = $params['limit'];
-			$offset = $params['page'];
 
-			// Build base query
-			$where = ['owner_id' => $user_id];
-
-			// Handle status filter
-			if ($status === 'read') {
-				// For multiple statuses, use raw query
-				$notifications = $this->getNotificationsWithMultipleStatuses(
-					$user_id,
-					['read', 'actioned'],
-					$type,
-					$limit,
-					$offset
-				);
-			} else {
-				// Single status - use fluent builder
-				if ($status !== 'all') {
-					$where['status'] = $status;
-				}
-
-				// Handle type filter
-				if ($type !== 'all' && isset($this->typeMap[$type])) {
-					$types = $this->typeMap[$type];
-					if (!empty($types)) {
-						// Multiple types - use raw query
-						return $this->getNotificationsByTypes(
-							$user_id,
-							$types,
-							$status,
-							$limit,
-							$offset
-						);
-					}
-				}
-
-				// Simple query - use fluent builder
-				$notifications = $this->notifications
-					->where($where)
-					->orderBy('created_at', 'DESC')
-					->limit($limit, $offset)
-					->getResults();
-			}
-
-			// Format notifications
-			return array_map([$this, 'formatNotification'], $notifications);
-		});
-	}
-
-	/**
-	 * Get notifications with multiple status values
-	 */
-	protected function getNotificationsWithMultipleStatuses(
-		int $user_id,
-		array $statuses,
-		string $type,
-		int $limit,
-		int $offset
-	): array {
-		$placeholders = implode(',', array_fill(0, count($statuses), '%s'));
-		$params = array_merge([$user_id], $statuses);
-
-		$typeCondition = '';
-		if ($type !== 'all' && isset($this->typeMap[$type])) {
-			$types = $this->typeMap[$type];
-			if (!empty($types)) {
-				$typePlaceholders = implode(',', array_fill(0, count($types), '%s'));
-				$typeCondition = "AND type IN ({$typePlaceholders})";
-				$params = array_merge($params, $types);
-			}
-		}
-
-		$params[] = $limit;
-		$params[] = $offset;
-
-		return $this->notifications->queryResults(
-			"SELECT * FROM {table}
-             WHERE owner_id = %d
-             AND status IN ({$placeholders})
-             {$typeCondition}
-             ORDER BY created_at DESC
-             LIMIT %d OFFSET %d",
-			$params
-		);
-	}
-
-	/**
-	 * Get notifications by multiple types
-	 */
-	protected function getNotificationsByTypes(
-		int $user_id,
-		array $types,
-		string $status,
-		int $limit,
-		int $offset
-	): array {
-		$placeholders = implode(',', array_fill(0, count($types), '%s'));
-		$params = array_merge([$user_id], $types, [$limit, $offset]);
-
-		$statusCondition = '';
-		if ($status !== 'all') {
-			$statusCondition = "AND status = %s";
-			array_splice($params, -2, 0, [$status]);
-		}
-
-		return $this->notifications->queryResults(
-			"SELECT * FROM {table}
-             WHERE owner_id = %d
-             AND type IN ({$placeholders})
-             {$statusCondition}
-             ORDER BY created_at DESC
-             LIMIT %d OFFSET %d",
-			$params
-		);
-	}
-
-	/**
-	 * Get approval notifications from the approval_requests table
-	 */
-	protected function getApprovalNotifications(int $user_id, string $status): array
-	{
-		$cacheKey = compact('user_id', 'status');
-
-		return $this->cache->remember($cacheKey, function() use ($user_id, $status) {
-			if (!$this->isVerifiedUser($user_id)) {
-				return [];
-			}
-
-			global $wpdb;
-			$formatted = [];
-
-			// Build status condition
-			$statusCondition = "1=1";
-			if ($status === 'unread') {
-				$statusCondition = "a.status = 'pending'";
-			} elseif ($status === 'read') {
-				$statusCondition = "a.status IN ('approved', 'rejected')";
-			} elseif ($status !== 'all') {
-				$statusCondition = $wpdb->prepare("a.status = %s", $status);
-			}
-
-			$approvals = Registrar::withFeature('approve_new');
-			foreach ($approvals as $type => $config) {
-				$table = $wpdb->prefix . BASE . 'approval_' . $type . 'requests';
-				$votes = $wpdb->prefix . BASE . 'approval_' . $type . 'votes';
-
-				$approvalRequests = $wpdb->get_results(
-					$wpdb->prepare(
-						"SELECT a.*,
-                        COALESCE(v.vote, 'none') as user_vote
-                        FROM {$table} a
-                        LEFT JOIN {$votes} v ON a.id = v.request_id AND v.user_id = %d
-                        WHERE a.user_id != %d
-                        AND {$statusCondition}
-                        ORDER BY a.created_at DESC",
-						$user_id,
-						$user_id
-					)
-				);
-
-				// Filter out requests created by current user
-				foreach ($approvalRequests as $approval) {
-					$requested_by = json_decode($approval->requested_by, true);
-
-					if (is_array($requested_by) && in_array($user_id, $requested_by)) {
-						continue;
-					}
-
-					$formatted[] = $this->formatApprovalNotification($approval);
-				}
-			}
-
-			return $formatted;
-		});
-	}
 
 	/**
 	 * Get content notifications for a user
@@ -1301,16 +1082,34 @@
 	{
 		$params = $request->get_params();
 
-		return [
-			'status' => in_array($params['status'] ?? '', ['all', 'unread', 'expired'])
+		$args = [
+			'status'	=> in_array($params['status']??'unread', ['all', 'unread', 'expired'])
 				? $params['status']
 				: 'unread',
-			'user_id' => get_current_user_id(),
-			'page' => absint($params['page'] ?? 1),
-			'type' => in_array($params['type'] ?? '', array_keys($this->manager->notification_types ?? []))
+			'type'		=> in_array($params['type'] ?? 'all', array_keys($this->manager->notification_types ?? []))
 				? $params['type']
 				: 'all',
+			'orderby'	=> $this->checkArray($params['orderby'], ['target_type', 'priority', 'created_at','read_at','actioned_at','action_taken','status'])??'created_at',
+			'order'		=> strtoupper($this->checkArray($params['order']??'DESC', ['desc','asc'])??'DESC'),
+			'page'		=> max(1, absint($params['page']??1)),
+			'per_page'	=> absint($params['per_page']??20),
 		];
+
+		foreach ($params as $param => $value) {
+			$result = match ($param) {
+				'target_id'		=> absint($value),
+				'target_type'	=> sanitize_text_field(strtolower($value)),
+				'from_user'		=> $this->checkUser(absint($value)),
+				'priority'		=> $this->checkArray($value, ['low','medium', 'high']),
+				'action_taken'	=> $value === 1 ? 1 : 0,
+				default => false
+			};
+			if ($result) {
+				$args[$param] = $result;
+			}
+		}
+
+		return $args;
 	}
 
 	/**

--
Gitblit v1.10.0