<?php
|
namespace JVBase\managers;
|
|
if (!defined('ABSPATH')) {
|
exit;
|
}
|
|
use JVBase\registrar\Registrar;
|
use JVBase\managers\CustomTable;
|
class VerifyEntryManager {
|
protected CustomTable $table;
|
protected int $max = 3;
|
public function __construct()
|
{
|
$this->defineTables();
|
}
|
|
protected function defineTables():void
|
{
|
$types = implode(',', array_map(function($item) { return "`{$item}`"; },Registrar::getFeatured('verify_entry')));
|
|
$table = CustomTable::for('verify_entry');
|
|
$table->setColumns([
|
'id' => 'bigint(20) unsigned NOT NULL AUTO_INCREMENT',
|
'user_id' => "{$table->getUserIDType()} NOT NULL",
|
'content_id' => "{$table->getPostIDType()} NOT NULL",
|
'content_type' => 'varchar(255) NOT NULL',
|
'term_id' => "{$table->getTermIDType()} NOT NULL",
|
'taxonomy' => "ENUM({$types}) NOT NULL",
|
'status' => "ENUM('requested', 'rejected','accepted') NOT NULL DEFAULT 'requested'",
|
'result' => 'JSON DEFAULT NULL',
|
'notes' => 'text DEFAULT NULL',
|
'created_date' => 'timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP',
|
'updated_date' => 'timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP',
|
]);
|
|
$table->setKeys([
|
['key' => 'PRIMARY', 'value' => '(`id`)'],
|
['key' => 'UNIQUE', 'value' => 'content_term (`content_id`, `term_id`)'],
|
'user_id (`user_id`)',
|
'term_id (`term_id`)',
|
'status (`term_id`, `status`)'
|
]);
|
|
$base = BASE;
|
$table->setConstraints([
|
"CONSTRAINT `{$base}verify_entry_user` FOREIGN KEY (`user_id`)
|
REFERENCES `{$table->getUserTable()}` (`ID`) ON DELETE CASCADE",
|
"CONSTRAINT `{$base}verify_entry_term` FOREIGN KEY (`term_id`)
|
REFERENCES `{$table->getTermTable()}` (`term_id`) ON DELETE CASCADE",
|
]);
|
|
$table->defineTable();
|
|
$this->table = $table;
|
}
|
protected function response(?bool $success = null, string $message = ''):array
|
{
|
$response = [
|
'success' => is_null($success) ? 'partial' : $success,
|
];
|
if (!empty($message)) {
|
$response['message'] = $message;
|
}
|
return $response;
|
}
|
|
public function requestEntry(int $userID, int $termID, string $taxonomy):array
|
{
|
$user = get_userdata($userID);
|
if (!$user || is_wp_error($user)) {
|
return $this->response(false, 'User does not exist');
|
}
|
$term = get_term($termID, jvbCheckBase($taxonomy));
|
if (!$term || is_wp_error($term)) {
|
return $this->response(false, 'Term does not exist');
|
}
|
|
$profile = get_user_meta($userID, BASE.'profile_link', true);
|
if (empty($profile)) {
|
return $this->response(false, 'No Profile found');
|
}
|
|
$managers = jvbGetTermOwners($termID);
|
if (in_array($userID, $managers)) {
|
wp_set_object_terms($profile, $termID, jvbCheckBase($taxonomy));
|
return $this->response(true, 'User is manager');
|
}
|
|
$total = $this->table->pluck('user_id', [
|
'user_id' => $userID,
|
'status' => 'requested'
|
]);
|
if (count($total) >= $this->max) {
|
return $this->response(false, 'User already has maximum requests');
|
}
|
|
$existing = $this->table->get([
|
'user_id' => $userID,
|
'term_id' => $termID
|
]);
|
if ($existing) {
|
return $this->response(false, 'Existing pending request found. Please wait for response.');
|
}
|
|
$request = $this->table->insert([
|
'user_id' => $userID,
|
'content_id'=> (int)$profile,
|
'content_type'=> jvbNoBase(get_post_type($profile)),
|
'term_id' => $termID,
|
'taxonomy' => jvbNoBase($taxonomy)
|
]);
|
|
if ($request && !empty($owners)) {
|
JVB()->notification()->notify($owners,'entry_requested',$userID, [
|
'target_id' => $termID,
|
'target_type' => $taxonomy
|
]);
|
}
|
return $this->response(true, 'Request has been sent');
|
}
|
|
protected function actionEntry(bool $approve, int $userID, int $requestID, ?string $notes = null):array
|
{
|
$request = $this->table->get(['id' => $requestID]);
|
if (!$request) {
|
return $this->response(false, 'Request does not exist');
|
}
|
|
$termID = $request['term_id'];
|
$owners = jvbGetTermOwners($termID);
|
if (!user_can($userID, 'can_manage_'.$termID) || !in_array($userID, $owners)) {
|
return $this->response(false, 'User does not exist');
|
}
|
$result = $this->table->update([
|
'status' => ($approve ? 'accepted' : 'rejected'),
|
'notes' => $notes
|
], [
|
'id' => $requestID
|
]);
|
if ($approve) {
|
wp_set_object_terms($request['content_id'], $termID, jvbCheckBase($request['taxonomy']));
|
}
|
|
JVB()->notification()?->notify($request['user_id'],$approve ? 'entry_approved' : 'entry_denied',$userID);
|
//TODO: What if there are multiple managers, and one approved the request? Do we just delete the notification?
|
JVB()->notification()?->unnotify($owners, 'entry_requested', $request['user_id'], [
|
'target_id' => $termID,
|
'target_type' => $request['taxonomy']
|
]);
|
return $this->response(true, 'Request has been '. $approve ? 'approved' : 'denied');
|
}
|
public function approveEntry(int $userID, int $requestID, ?string $notes = null):array
|
{
|
return $this->actionEntry(true, $userID, $requestID, $notes);
|
}
|
|
public function denyEntry(int $userID, int $requestID, ?string $notes = null):array
|
{
|
return $this->actionEntry(false, $userID, $requestID, $notes);
|
}
|
}
|