<?php
|
|
namespace JVBase\rest\routes;
|
|
use JVBase\Instance;
|
use JVBase\managers\Approvals;
|
use JVBase\managers\Cache;
|
|
use JVBase\registrar\Registrar;
|
use JVBase\rest\PermissionHandler;
|
use JVBase\rest\Rest;
|
use JVBase\rest\Route;
|
use JVBase\rest\Response;
|
use JVBase\base\Site;
|
use WP_REST_Request;
|
use WP_REST_Response;
|
|
if (!defined('ABSPATH')) {
|
exit; // Exit if accessed directly
|
}
|
|
class ApprovalRoutes extends Rest
|
{
|
use Instance;
|
protected array $userTypes;
|
protected array $termTypes;
|
protected array $allTypes;
|
|
protected int $expiryDays = 7;
|
protected bool $hasMemberApproval = false;
|
|
public function __construct()
|
{
|
$this->cacheName = 'approvals';
|
$this->hasMemberApproval = Site::membership() && Site::membership()->has('member_verified');
|
parent::__construct();
|
$this->cache = Cache::for('approvals', 'custom', $this->cacheTtl);
|
|
$this->initTypes();
|
}
|
|
protected function initTypes():void
|
{
|
$this->userTypes = [];
|
$this->termTypes = [];
|
$this->allTypes = [];
|
if ($this->hasMemberApproval) {
|
$this->userTypes = Registrar::withFeature('approve_new', 'user');
|
$this->allTypes = $this->userTypes;
|
}
|
if (Site::has('term_approval')) {
|
$this->termTypes = Registrar::withFeature('approve_new', 'term');
|
$this->allTypes[] = 'term';
|
}
|
}
|
|
public function registerRoutes():void
|
{
|
Route::for('approvals')
|
->get([$this, 'getApprovals'])
|
->args([
|
'type' => 'string',
|
'status' => 'string|enum:pending,approved,rejected,expired',
|
])
|
->auth(PermissionHandler::combine(['user', 'verified']))
|
->rateLimit(30)
|
->post([$this, 'handleAction'])
|
->args([
|
'request_id' => 'integer|required',
|
'action' => 'string|required|enum:approve,reject',
|
'type' => 'string|required',
|
'notes' => 'string',
|
])
|
->auth(PermissionHandler::combine(['user', 'verified']))
|
->rateLimit(3)
|
->register();
|
}
|
|
|
/**
|
* @param WP_REST_Request $request
|
*
|
* @return WP_REST_Response
|
*/
|
public function handleAction(WP_REST_Request $request):WP_REST_Response
|
{
|
$data = $request->get_params();
|
$request_id = absint($data['request_id']);
|
$user_id = get_current_user_id();
|
$action = sanitize_text_field($data['action']);
|
$type = sanitize_text_field($data['type']);
|
$notes = sanitize_text_field($data['notes'] ?? '');
|
|
if (!in_array($type, $this->allTypes)) {
|
return Response::validationError(['message' => 'Invalid type']);
|
}
|
|
$result = $this->handleVote($type, $action, $request_id, $user_id, $notes);
|
|
return $result
|
? Response::success(['message' => 'Vote recorded successfully'])
|
: Response::error('Failed to record vote');
|
}
|
|
/**
|
* Artist and Term Approvals
|
*/
|
protected function handleVote(string $type, string $vote, int $request_id, int $user_id, string $notes = ''): bool
|
{
|
if (!in_array($vote, ['approve', 'reject', 'dismiss'])) {
|
return false;
|
}
|
$result = Approvals::getInstance()->markApproval($request_id, $user_id, $type, $vote, $notes);
|
return $result['success'];
|
}
|
|
|
protected function rebuildExpiryDate()
|
{
|
return date('Y-m-d H:i:s', strtotime("+{$this->expiryDays} days", time()));
|
}
|
|
|
|
/*************
|
* Artist Approvals
|
************/
|
/**
|
* Record an approval vote for an artist
|
*
|
* @param int $user_id User casting the approval vote
|
* @param int $request_id The approval request ID
|
* @param string $vote 'approve' or 'reject'
|
* @param string $notes Optional notes for the vote
|
*
|
* @return bool Success status
|
*/
|
public function voteForArtist(int $user_id, int $request_id, string $vote, string $notes = ''):bool
|
{
|
return $this->handleVote(jvbUserRole($user_id), $vote, $request_id, $user_id, $notes);
|
}
|
|
|
/**
|
* Get verification details for a request
|
*
|
* @param int $requestID the request ID
|
* @param string $type Type
|
*
|
* @return array|false Verification details or false if not verified
|
*/
|
public function getVerificationDetails(int $requestID, string $type): array|false
|
{
|
$request = Approvals::getInstance()->getRequest($requestID, $type);
|
if (!$request) {
|
return false;
|
}
|
$votes = Approvals::getInstance()->getVotes($requestID, $type);
|
|
// Join with user data for display names
|
foreach ($votes as &$vote) {
|
$user = get_userdata($vote['user_id']);
|
$vote['approver_name'] = $user ? jvbGetUsername($vote['user_id']) : 'Someone';
|
}
|
|
return [
|
'request' => $request,
|
'votes' => $votes,
|
'verification_date' => $request['updated_at'],
|
];
|
}
|
|
|
|
/**
|
* Create a new term approval request
|
*
|
* @param int $user_id User requesting approval
|
* @param string $taxonomy Taxonomy
|
* @param string $name New Term Name
|
* @param int $parent Parent Term ID
|
* @param int $required_approvals Number of approvals required
|
*
|
* @return int|false Request ID or false on failure
|
*/
|
public function createTermApprovalRequest(
|
int $user_id,
|
string $taxonomy,
|
string $name,
|
int $parent = 0,
|
int $required_approvals = 3
|
): int|false {
|
|
$result = Approvals::getInstance()->createApproval(
|
$user_id,
|
$taxonomy,
|
$name,
|
$parent
|
);
|
return $result['success'];
|
}
|
|
public function getApprovals(WP_REST_Request $request): WP_REST_Response
|
{
|
$user_id = get_current_user_id();
|
$type = sanitize_text_field($request->get_param('type') ?? 'all');
|
$status = sanitize_text_field($request->get_param('status') ?? 'pending');
|
|
$result = Approvals::getInstance()->getApprovalRequests($user_id, $type === 'all' ? null : $type);
|
|
return $this->success($result);
|
}
|
|
|
}
|