From fff721dd185f5b97f7ae7a6e64189e55887ff590 Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Sun, 05 Jul 2026 18:36:57 +0000
Subject: [PATCH] =Cleaning up the Square integration (still a bit more to do yet). Also majorly overhauled /rest/ files to ignore a rest request 'user' paramater, and rely on get_current_user_id() instead.

---
 inc/rest/routes/ApprovalRoutes.php |  557 +-----------------------------------------------------
 1 files changed, 19 insertions(+), 538 deletions(-)

diff --git a/inc/rest/routes/ApprovalRoutes.php b/inc/rest/routes/ApprovalRoutes.php
index fe5db06..b4129a7 100644
--- a/inc/rest/routes/ApprovalRoutes.php
+++ b/inc/rest/routes/ApprovalRoutes.php
@@ -33,24 +33,19 @@
         parent::__construct();
 
         $this->initTypes();
-
-        if ($this->hasMemberApproval) {
-            add_action('user_register', [$this, 'handleNewUserRegistration'], 10, 2);
-        }
-
-        add_action('jvb_cleanup_expired_approvals', [$this, 'cleanupExpiredApprovals']);
     }
 
     protected function initTypes():void
     {
         $this->userTypes = [];
         $this->termTypes = [];
+		$this->allTypes = [];
         if ($this->hasMemberApproval) {
-            $this->userTypes = Registrar::getFeatured('approve_new', 'user');
+            $this->userTypes = Registrar::withFeature('approve_new', 'user');
             $this->allTypes = $this->userTypes;
         }
         if (Site::has('term_approval')) {
-            $this->termTypes = Registrar::getFeatured('approve_new', 'term');
+            $this->termTypes = Registrar::withFeature('approve_new', 'term');
             $this->allTypes[] = 'term';
         }
     }
@@ -60,7 +55,6 @@
 		Route::for('approvals')
 			->get([$this, 'getApprovals'])
 			->args([
-				'user' => 'integer|required',
 				'type' => 'string',
 				'status' => 'string|enum:pending,approved,rejected,expired',
 			])
@@ -68,7 +62,6 @@
 			->rateLimit(30)
 			->post([$this, 'handleAction'])
 			->args([
-				'user' => 'integer|required',
 				'request_id' => 'integer|required',
 				'action' => 'string|required|enum:approve,reject',
 				'type' => 'string|required',
@@ -79,27 +72,6 @@
 			->register();
     }
 
-    /**
-     * Handler for user registration
-     *
-     * @param int $user_id New user ID
-     * @param object $user the new user object
-     *
-     * @return void
-     */
-	public function handleNewUserRegistration(int $user_id, object $user): void
-	{
-		$intersect = array_intersect(
-			array_map(fn($role) => BASE.$role, $this->userTypes),
-			(array) $user->roles
-		);
-
-		if (!empty($intersect)) {
-			$user->add_cap('skip_moderation', false);
-			$this->createArtistApprovalRequest($user_id);
-		}
-	}
-
 
     /**
      * @param WP_REST_Request $request
@@ -110,7 +82,7 @@
     {
 		$data = $request->get_params();
 		$request_id = absint($data['request_id']);
-		$user_id = absint($data['user']);
+		$user_id = get_current_user_id();
 		$action = sanitize_text_field($data['action']);
 		$type = sanitize_text_field($data['type']);
 		$notes = sanitize_text_field($data['notes'] ?? '');
@@ -131,255 +103,25 @@
      */
 	protected function handleVote(string $type, string $vote, int $request_id, int $user_id, string $notes = ''): bool
 	{
-		if (!in_array($vote, ['approve', 'reject'])) {
+		if (!in_array($vote, ['approve', 'reject', 'dismiss'])) {
 			return false;
 		}
-
-		$requestTable = $this->getTableName($type, 'requests');
-		$voteTable = $this->getTableName($type, 'votes');
-
-		$requests = CustomTable::for($requestTable);
-		$votes = CustomTable::for($voteTable);
-
-		try {
-			return $requests->transaction(function($requests) use ($votes, $request_id, $user_id, $vote, $notes, $type) {
-				// Get the approval request
-				$request = $requests->where(['id' => $request_id])->first();
-
-				if (!$request || $request->status !== 'pending') {
-					throw new Exception("Invalid approval request");
-				}
-
-				// Check if user already voted
-				$existingVote = $votes->where([
-					'request_id' => $request_id,
-					'user_id' => $user_id
-				])->first();
-
-				if ($existingVote) {
-					if ($existingVote->vote !== $vote) {
-						// Update vote
-						$votes->where(['id' => $existingVote->id])
-							->updateResults(['vote' => $vote]);
-						return true;
-					}
-					throw new Exception("User has already voted on this request");
-				}
-
-				// Insert new vote
-				$votes->create([
-					'request_id' => $request_id,
-					'user_id' => $user_id,
-					'vote' => $vote,
-					'notes' => $notes,
-				]);
-
-				// Update request based on vote type
-				$user = get_userdata($user_id);
-
-				if ($vote === 'approve') {
-					$this->handleApproval($requests, $request, $request_id, $user, $type);
-				} else {
-					$this->handleRejection($requests, $request, $request_id, $user, $type);
-				}
-
-				return true;
-			});
-		} catch (Exception $e) {
-			$this->logError('handleVote', [
-				'error' => $e->getMessage(),
-				'user_id' => $user_id,
-				'request_id' => $request_id,
-				'vote' => $vote
-			]);
-			return false;
-		}
+		$result = JVB()->approvals()->markApproval($request_id, $user_id, $type, $vote, $notes);
+		return $result['success'];
 	}
 
-	/**
-	 * Handle approval vote logic
-	 */
-	protected function handleApproval(CustomTable $table, object $request, int $request_id, $user, string $type): void
-	{
-		$approvers = json_decode($request->approved_by, true) ?: [];
-		$approvers[$user->ID] = [
-			'name' => $user->display_name,
-			'voted' => current_time('mysql')
-		];
 
-		$table->where(['id' => $request_id])->updateResults([
-			'current_approvals' => $request->current_approvals + 1,
-			'approved_by' => json_encode($approvers),
-			'expires_at' => $this->rebuildExpiryDate()
-		]);
-
-		// Check if threshold met
-		if ($request->current_approvals + 1 >= $request->required_approvals) {
-			match ($type) {
-				'term' => $this->makeTermLive($request),
-				default => $this->completeVerification($request_id, $type),
-			};
-		}
-	}
-
-	/**
-	 * Handle rejection vote logic
-	 */
-	protected function handleRejection(CustomTable $table, object $request, int $request_id, $user, string $type): void
-	{
-		$rejecters = json_decode($request->rejected_by, true) ?: [];
-		$rejecters[$user->ID] = [
-			'name' => $user->display_name,
-			'voted' => current_time('mysql')
-		];
-
-		$table->where(['id' => $request_id])->updateResults([
-			'current_rejections' => $request->current_rejections + 1,
-			'rejected_by' => json_encode($rejecters),
-			'expires_at' => $this->rebuildExpiryDate()
-		]);
-
-		// Check if threshold met
-		if ($request->current_rejections + 1 >= $request->required_approvals) {
-			match ($type) {
-				'term' => $this->makeTermUnalive($request),
-				default => $this->denyVerification($request_id, $type),
-			};
-		}
-	}
     protected function rebuildExpiryDate()
     {
         return date('Y-m-d H:i:s', strtotime("+{$this->expiryDays} days", time()));
     }
 
-    /**
-     * @param string $type user/artist or term
-     * @param array $request
-     *
-     * @return bool|int
-     */
-	protected function createApprovalRequest(string $type, array $request): int
-	{
-		$tableName = $this->getTableName($type, 'requests');
 
-		$id = CustomTable::for($tableName)->create($request);
-
-		if (!$id) {
-			throw new Exception('Failed to create approval request');
-		}
-
-		return $id;
-	}
 
     /*************
      * Artist Approvals
      ************/
     /**
-     * Create artist approval request
-     *
-     * @param int $user_id User ID to be approved
-     *
-     * @return int|false Request ID or false on failure
-     */
-	/**
-	 * Create artist approval request - REFACTORED
-	 */
-	public function createArtistApprovalRequest(int $user_id): int|false
-	{
-		$userRole = jvbUserRole($user_id);
-		$tableName = $this->getTableName($userRole, 'requests');
-		$table = CustomTable::for($tableName);
-
-		try {
-			return $table->transaction(function($table) use ($user_id) {
-				// Check for existing request
-				$existing = $table->where(['user_id' => $user_id])->first();
-
-				if ($existing) {
-					return $existing->id;
-				}
-
-				$user_data = get_userdata($user_id);
-
-				return $table->create([
-					'user_id' => $user_id,
-					'status' => 'pending',
-					'expires_at' => date('Y-m-d H:i:s', strtotime('+30 days')),
-					'current_approvals' => 0,
-					'current_rejections' => 0,
-					'required_approvals' => 3, // From config
-					'approved_by' => json_encode([]),
-					'rejected_by' => json_encode([]),
-				]);
-			});
-		} catch (Exception $e) {
-			$this->logError('createArtistApprovalRequest', [
-				'error' => $e->getMessage(),
-				'user_id' => $user_id
-			]);
-			return false;
-		}
-	}
-
-    /**
-     * Mark an artist as verified
-     *
-     * @param int $user_id The user to verify
-     * @param int $verified_by ID of user who verified them (optional)
-     *
-     * @return bool Success status
-     */
-    public function verifyArtist(int $user_id, int $verified_by = 0):bool
-    {
-        $user = get_userdata($user_id);
-
-        // Check if user has the artist role
-        if (!array_intersect(array_map(function ($role) { return BASE.$role; }, $this->userTypes), $user->roles)) {
-            return false;
-        }
-
-        // Add the capability
-        $user->add_cap('skip_moderation', true);
-
-        // Store verification metadata
-        update_user_meta($user_id, BASE . 'verification_date', current_time('mysql'));
-        if ($verified_by) {
-            update_user_meta($user_id, BASE . 'verified_by', $verified_by);
-        }
-
-        return true;
-    }
-
-    /**
-     * Mark an artist as verified
-     *
-     * @param int $user_id The user to verify
-     * @param int $verified_by ID of user who verified them (optional)
-     *
-     * @return bool Success status
-     */
-    public function unverifyArtist(int $user_id, int $verified_by = 0):bool
-    {
-        $user = get_userdata($user_id);
-
-        // Check if user has the artist role
-        if (!array_intersect(array_map(function ($role) { return BASE.$role; }, $this->userTypes), $user->roles)) {
-            return false;
-        }
-
-        // Add the capability
-        $user->add_cap('skip_moderation', false);
-
-        // Store verification metadata
-        update_user_meta($user_id, BASE . 'unverification_date', current_time('mysql'));
-        if ($verified_by) {
-            update_user_meta($user_id, BASE . 'unverified_by', $verified_by);
-        }
-
-        return true;
-    }
-
-    /**
      * Record an approval vote for an artist
      *
      * @param int $user_id User casting the approval vote
@@ -394,57 +136,6 @@
         return $this->handleVote(jvbUserRole($user_id), $vote, $request_id, $user_id, $notes);
     }
 
-	/**
-	 * Complete verification - REFACTORED
-	 */
-	protected function completeVerification(int $request_id, string $type = 'artist'): void
-	{
-		$tableName = $this->getTableName($type, 'requests');
-		$table = CustomTable::for($tableName);
-
-		$table->where(['id' => $request_id])->updateResults([
-			'status' => 'approved',
-			'approved_at' => current_time('mysql')
-		]);
-
-		$request = $table->where(['id' => $request_id])->first();
-
-		if ($request && $request->user_id) {
-			$user = new \WP_User($request->user_id);
-			$user->add_cap('skip_moderation', true);
-
-			JVB()->notification()->addNotification(
-				$request->user_id,
-				'approval_granted',
-				['message' => 'Your account has been verified!']
-			);
-		}
-
-		$this->cache->flush();
-	}
-
-	protected function denyVerification(int $request_id, string $type = 'artist'): void
-	{
-		$tableName = $this->getTableName($type, 'requests');
-		$table = CustomTable::for($tableName);
-
-		$table->where(['id' => $request_id])->updateResults([
-			'status' => 'rejected',
-			'rejected_at' => current_time('mysql')
-		]);
-
-		$request = $table->where(['id' => $request_id])->first();
-
-		if ($request && $request->user_id) {
-			JVB()->notification()->addNotification(
-				$request->user_id,
-				'approval_denied',
-				['message' => 'Your verification request was not approved.']
-			);
-		}
-
-		$this->cache->flush();
-	}
 
     /**
      * Get verification details for a request
@@ -456,25 +147,16 @@
      */
 	public function getVerificationDetails(int $requestID, string $type): array|false
 	{
-		$requestTable = CustomTable::for($this->getTableName($type, 'requests'));
-		$voteTable = CustomTable::for($this->getTableName($type, 'votes'));
-
-		$request = $requestTable->where(['id' => $requestID])->first(ARRAY_A);
-
+		$request = JVB()->approvals()->getRequest($requestID, $type);
 		if (!$request) {
 			return false;
 		}
-
-		// Get the votes for this request
-		$votes = $voteTable
-			->where(['request_id' => $request['id']])
-			->orderBy('created_at', 'ASC')
-			->getResults(ARRAY_A);
+		$votes = JVB()->approvals()->getVotes($requestID, $type);
 
 		// Join with user data for display names
 		foreach ($votes as &$vote) {
 			$user = get_userdata($vote['user_id']);
-			$vote['approver_name'] = $user ? $user->display_name : 'Unknown';
+			$vote['approver_name'] = $user ? jvbGetUsername($vote['user_id']) : 'Someone';
 		}
 
 		return [
@@ -484,139 +166,7 @@
 		];
 	}
 
-    /*************
-     * Term Approvals
-     ************/
-    public function voteForTerm(int $user_id, int $request_id, string $vote, string $notes = ''):bool
-    {
-        return $this->handleVote('term', $vote, $user_id, $request_id, $notes);
-    }
 
-    /**
-     * Publish an approved term
-     *
-     * @param object $request Approval request object
-     *
-     * @return boolean Success or failure
-     */
-	protected function makeTermLive(object $request): bool
-	{
-		try {
-			$taxonomy = $request->taxonomy;
-			$term_name = $request->name;
-			$parent = $request->parent;
-
-			$result = wp_insert_term($term_name, $taxonomy, [
-				'parent' => $parent
-			]);
-
-			if (is_wp_error($result)) {
-				throw new Exception($result->get_error_message());
-			}
-
-			$term_id = $result['term_id'];
-
-			// Update request status
-			CustomTable::for($this->getTableName('term', 'requests'))
-				->where(['id' => $request->id])
-				->updateResults([
-					'status' => 'approved',
-					'created_term' => $term_id
-				]);
-
-			$userIDs = [];
-			$approvedBy = [];
-			$approvers = json_decode($request->approved_by, true) ?: [];
-			$requesters = json_decode($request->requested_by, true) ?: [];
-			$rejectors = json_decode($request->rejected_by, true) ?: [];
-
-			foreach (array_merge($requesters, $approvers, $rejectors) as $user_id => $info) {
-				$userIDs[] = $user_id;
-			}
-			foreach ($approvers as $user_id => $info) {
-				$approvedBy[] = $info['name'];
-			}
-
-			$approvedBy = jvbCommaList($approvedBy);
-
-			JVB()->notification()->addNotification(
-				$userIDs,
-				'term_approved',
-				[
-					'term_id' => $term_id,
-					'term_name' => $term_name,
-					'taxonomy' => $taxonomy,
-					'approved_by' => $approvedBy
-				]
-			);
-
-			return true;
-		} catch (Exception $e) {
-			$this->logError('makeTermLive', [
-				'error' => $e->getMessage(),
-				'request_id' => $request->id,
-				'term_name' => $term_name ?? '',
-				'taxonomy' => $taxonomy ?? ''
-			]);
-
-			return false;
-		}
-	}
-    /**
-     * Reject a proposed term
-     *
-     * @param object $request request object
-     *
-     * @return boolean Success or failure
-     */
-	protected function makeTermUnalive(object $request): bool
-	{
-		try {
-			// Update request status
-			CustomTable::for($this->getTableName('term', 'requests'))
-				->where(['id' => $request->id])
-				->updateResults([
-					'status' => 'rejected'
-				]);
-
-			$userIDs = [];
-			$rejectedBy = [];
-
-			$approvers = json_decode($request->approved_by, true) ?: [];
-			$requesters = json_decode($request->requested_by, true) ?: [];
-			$rejectors = json_decode($request->rejected_by, true) ?: [];
-
-			foreach (array_merge($requesters, $approvers, $rejectors) as $user_id => $info) {
-				$userIDs[] = $user_id;
-			}
-			foreach ($rejectors as $user_id => $info) {
-				$rejectedBy[] = $info['name'];
-			}
-
-			$rejectedBy = jvbCommaList($rejectedBy);
-
-			JVB()->notification()->addNotification(
-				$userIDs,
-				'term_rejected',
-				[
-					'term_name' => $request->name,
-					'taxonomy' => $request->taxonomy,
-					'rejected_by' => $rejectedBy
-				]
-			);
-
-			return true;
-		} catch (Exception $e) {
-			$this->logError('makeTermUnalive', [
-				'error' => $e->getMessage(),
-				'request_id' => $request->id,
-				'term_name' => $request->name ?? '',
-				'taxonomy' => $request->taxonomy ?? ''
-			]);
-
-			return false;
-		}
-	}
 
     /**
      * Create a new term approval request
@@ -636,80 +186,14 @@
 		int $parent = 0,
 		int $required_approvals = 3
 	): int|false {
-		$table = CustomTable::for($this->getTableName('term', 'requests'));
 
-		try {
-			return $table->transaction(function($table) use ($user_id, $taxonomy, $name, $parent, $required_approvals) {
-				// Check for existing request
-				$existing = $table->where([
-					'name' => $name,
-					'taxonomy' => $taxonomy,
-					'parent' => $parent,
-					'status' => 'pending'
-				])->first();
-
-				if ($existing) {
-					$requestedBy = json_decode($existing->requested_by, true) ?: [];
-
-					if (isset($requestedBy[$user_id])) {
-						return (int)$existing->id;
-					}
-
-					$requestedBy[$user_id] = get_userdata($user_id)->display_name;
-
-					$table->where(['id' => $existing->id])->updateResults([
-						'requested_by' => json_encode($requestedBy)
-					]);
-
-					return (int)$existing->id;
-				}
-
-				// Create new request
-				return $this->createApprovalRequest('term', [
-					'taxonomy' => $taxonomy,
-					'name' => $name,
-					'parent' => $parent ?: null,
-					'status' => 'pending',
-					'required_approvals' => $required_approvals,
-					'current_approvals' => 0,
-					'current_rejections' => 0,
-					'requested_by' => json_encode([$user_id => get_userdata($user_id)->display_name]),
-					'expires_at' => date('Y-m-d H:i:s', strtotime('+30 days')),
-				]);
-			});
-		} catch (Exception $e) {
-			$this->logError('createTermApprovalRequest', [
-				'error' => $e->getMessage(),
-				'user_id' => $user_id,
-				'taxonomy' => $taxonomy,
-				'name' => $name
-			]);
-
-			return false;
-		}
-	}
-    /**
-     * Clean up expired approval requests and notify admin
-     *
-     * @return void
-     */
-	public function cleanupExpiredApprovals(): void
-	{
-		$now = current_time('mysql');
-
-		foreach ($this->allTypes as $type) {
-			$tableName = $this->getTableName($type, 'requests');
-
-			CustomTable::for($tableName)->query(
-				"UPDATE {table}
-                 SET status = 'expired'
-                 WHERE status = 'pending'
-                   AND expires_at < %s",
-				[$now]
-			);
-		}
-
-		$this->cache->flush();
+		$result = JVB()->approvals()->createApproval(
+			$user_id,
+			$taxonomy,
+			$name,
+			$parent
+		);
+		return $result['success'];
 	}
 
 	protected function getTableName(string $type, string $suffix): string
@@ -722,14 +206,10 @@
 
 	public function getApprovals(WP_REST_Request $request): WP_REST_Response
 	{
-		$user_id = absint($request->get_param('user'));
+		$user_id = get_current_user_id();
 		$type = sanitize_text_field($request->get_param('type') ?? 'all');
 		$status = sanitize_text_field($request->get_param('status') ?? 'pending');
 
-		if (!$this->checkUser($user_id)) {
-			return $this->unauthorized();
-		}
-
 		$cacheKey = compact('user_id', 'type', 'status');
 
 		$result = $this->cache->remember($cacheKey, function() use ($type, $status) {
@@ -751,6 +231,7 @@
 
 	private function getUserApprovals(string $status = 'pending'): array
 	{
+
 		$table = CustomTable::for($this->getTableName('artist', 'requests'));
 
 		$query = $table;

--
Gitblit v1.10.0