<?php
|
namespace JVBase\rest\routes;
|
|
use JVBase\Instance;
|
use JVBase\JVB;
|
use JVBase\managers\Cache;
|
use JVBase\managers\NotificationManager;
|
use JVBase\managers\Notifications\Notifications;
|
use JVBase\managers\Responses;
|
use JVBase\rest\Rest;
|
use JVBase\managers\CustomTable;
|
use WP_REST_Request;
|
use WP_REST_Response;
|
use WP_Error;
|
|
if (!defined('ABSPATH')) {
|
exit;
|
}
|
|
/**
|
* Response Routes
|
*
|
* Handles threaded responses/comments for news items
|
*/
|
class ResponseRoutes extends Rest
|
{
|
use Instance;
|
protected int $perPage = 20;
|
protected CustomTable $table;
|
protected CustomTable $karmaTable;
|
|
public function __construct()
|
{
|
$this->cacheName = 'responses';
|
$this->cacheTtl = 1800; // 30 minutes
|
parent::__construct();
|
$this->cache = Cache::for($this->cacheName, 'response', $this->cacheTtl);
|
|
}
|
|
public function registerRoutes(): void
|
{
|
register_rest_route($this->namespace, '/response', [
|
[
|
'methods' => 'GET',
|
'callback' => [$this, 'getResponses'],
|
'permission_callback' => 'is_user_logged_in'
|
],
|
[
|
'methods' => 'POST',
|
'callback' => [$this, 'handleResponseActions'],
|
'permission_callback' => 'is_user_logged_in'
|
]
|
]);
|
}
|
|
/**
|
* Get responses for an item
|
*/
|
public function getResponses(WP_REST_Request $request): WP_REST_Response
|
{
|
$params = $request->get_params();
|
if (!array_key_exists('item_id', $params)) {
|
return $this->error('Missing item ID', 'missing_item_id');
|
}
|
$item_id = absint($params['item_id']);
|
|
$args = $this->buildQueryArgs($request);
|
|
return $this->success(Responses::getInstance()->getAllItemResponses($item_id, $args));
|
}
|
|
/**
|
* Handle response actions (create/update/delete)
|
*/
|
public function handleResponseActions(WP_REST_Request $request): WP_REST_Response
|
{
|
$data = $request->get_params();
|
$user_id = get_current_user_id();
|
|
if (!$user_id) {
|
return $this->unauthorized();
|
}
|
|
$action = sanitize_text_field($data['action'] ?? '');
|
|
if (!in_array($action, ['create', 'delete', 'update'])) {
|
return $this->error('Invalid action', 'invalid_action');
|
}
|
|
// Validate required fields for create
|
if ($action === 'create') {
|
if (!isset($data['item_id'], $data['response'], $data['content'])) {
|
return $this->error('Missing required fields', 'missing_fields');
|
}
|
}
|
$responses = Responses::getInstance();
|
$response = match($action) {
|
'create' => $responses->respondTo(
|
absint($data['item_id']),
|
sanitize_text_field($data['content']),
|
$user_id,
|
wp_kses_post($data['response']),
|
isset($data['parent_id']) ? absint($data['parent_id']) : null
|
),
|
'update' => $responses->editResponse(
|
absint($data['response_id']),
|
wp_kses_post($data['response']??'')
|
),
|
'delete' => $responses->deleteResponse(absint($data['response_id']))
|
};
|
|
if ($response['success']) {
|
return $this->success($response);
|
}
|
return $this->error($response['message']);
|
}
|
|
/**
|
* Get responses with karma calculations
|
*/
|
protected function getItemResponse(int $item_id, array $args = []): array|WP_Error
|
{
|
$responses = Responses::getInstance()->getAllItemResponses($item_id, $args);
|
// Format responses
|
$responses['items'] = array_map([$this, 'formatItem'], $responses);
|
|
return $responses;
|
}
|
|
/**
|
* Build query arguments from request
|
*/
|
protected function buildQueryArgs(WP_REST_Request $request): array
|
{
|
$page = max(1, (int) ($request->get_param('page') ?? 1));
|
$per_page = min(100, max(1, (int) ($request->get_param('per_page') ?? $this->perPage)));
|
|
$args = [
|
'page' => $page,
|
'per_page' => $per_page,
|
'orderby' => 'created_at',
|
'order' => 'DESC'
|
];
|
|
// Parent filter (null = top-level only)
|
if ($request->has_param('parent_id')) {
|
$parent_id = $request->get_param('parent_id');
|
$args['parent_id'] = $parent_id === '0' ? null : (int) $parent_id;
|
}
|
|
// Ordering
|
if ($request->has_param('orderby')) {
|
$orderby = $request->get_param('orderby');
|
$valid = ['created_at', 'updated_at', 'upvotes', 'downvotes', 'karmic_score'];
|
|
if (in_array($orderby, $valid)) {
|
$args['orderby'] = $orderby;
|
}
|
}
|
|
if ($request->has_param('order')) {
|
$order = strtoupper($request->get_param('order'));
|
if (in_array($order, ['ASC', 'DESC'])) {
|
$args['order'] = $order;
|
}
|
}
|
|
return $args;
|
}
|
|
/**
|
* Format response for API output
|
*/
|
protected function formatItem(array $response): array
|
{
|
// Handle deleted users
|
if ($response['is_user_deleted']) {
|
$response['user'] = [
|
'id' => null,
|
'name' => '[deleted user]',
|
'is_deleted' => true
|
];
|
} else {
|
$user = get_userdata($response['user_id']);
|
$response['user'] = [
|
'id' => $response['user_id'],
|
'name' => $user->display_name,
|
'url' => jvbUserProfileLink($response['user_id']),
|
];
|
}
|
|
return $response;
|
}
|
}
|