From a9b3b28d001941921aa70d37fdc87c758a163a44 Mon Sep 17 00:00:00 2001
From: Jake Vanderwerf <get@jakevanderwerf.ca>
Date: Fri, 05 Jun 2026 16:47:03 +0000
Subject: [PATCH] =Some hefty changes to FeedBlock. Transitioning to loading first page in php to save on extra requests. Got a bit to do yet, but I have to work on Northeh for a bit here.
---
inc/rest/routes/ApprovalRoutes.php | 543 +----------------------------------------------------
1 files changed, 15 insertions(+), 528 deletions(-)
diff --git a/inc/rest/routes/ApprovalRoutes.php b/inc/rest/routes/ApprovalRoutes.php
index fe5db06..a051459 100644
--- a/inc/rest/routes/ApprovalRoutes.php
+++ b/inc/rest/routes/ApprovalRoutes.php
@@ -33,18 +33,13 @@
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->allTypes = $this->userTypes;
@@ -79,27 +74,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
@@ -131,255 +105,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 +138,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 +149,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 +168,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 +188,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
@@ -751,6 +237,7 @@
private function getUserApprovals(string $status = 'pending'): array
{
+
$table = CustomTable::for($this->getTableName('artist', 'requests'));
$query = $table;
--
Gitblit v1.10.0