| | |
| | | <?php |
| | | namespace JVBase\rest; |
| | | |
| | | use JVBase\inc\managers\ErrorHelper; |
| | | use JVBase\integrations\services\Cloudflare; |
| | | use JVBase\managers\Cache; |
| | | use JVBase\managers\Errors; |
| | | use JVBase\meta\Meta; |
| | | use JVBase\registrar\Registrar; |
| | | use JVBase\base\Site; |
| | | use JVBase\rest\routes\TermRoutes; |
| | | use WP_REST_Request; |
| | | use WP_REST_Response; |
| | | use Exception; |
| | |
| | | */ |
| | | abstract class Rest |
| | | { |
| | | use ErrorHelper; |
| | | protected string $namespace = 'jvb/v1'; |
| | | protected ?Cache $cache = null; |
| | | protected string $cacheName = ''; |
| | | protected int $cacheTtl = 3600; |
| | | protected int $cacheTtl = HOUR_IN_SECONDS; |
| | | protected static ?string $action; |
| | | |
| | | public function __construct() |
| | |
| | | $this->cache = Cache::for($this->cacheName, $this->cacheTtl); |
| | | } |
| | | |
| | | add_action('rest_api_init', [$this, 'registerRoutes']); |
| | | add_action('rest_api_init', [$this, 'registerRoutes'], 10); |
| | | add_action('rest_api_init', [$this, 'ensureDefinitions'], 9); |
| | | } |
| | | |
| | | public function ensureDefinitions():void |
| | | { |
| | | Site::getInstance(); |
| | | Registrar::ensureInstanced(); |
| | | } |
| | | /** |
| | | * Register routes - implement using Route builder |
| | | */ |
| | |
| | | /** |
| | | * Convert MySQL datetime to ISO 8601 timestamp |
| | | */ |
| | | protected function formatTimestamp(?string $mysqlDatetime): ?string |
| | | public function formatTimestamp(?string $mysqlDatetime): ?string |
| | | { |
| | | return Response::formatTimestamp($mysqlDatetime); |
| | | } |
| | |
| | | |
| | | // Keep existing author filtering logic |
| | | $authorQuery = []; |
| | | foreach (Registrar::getFeatured('can_create', 'user') as $type) { |
| | | foreach (Registrar::withFeature('can_create', 'user') as $type) { |
| | | if (array_key_exists($type, $data)) { |
| | | $artist_ids = array_map( |
| | | 'absint', |
| | |
| | | */ |
| | | protected function checkUser(int $userId): bool |
| | | { |
| | | $cache = Cache::for('checkUser', DAY_IN_SECONDS)->connect('user'); |
| | | $cache = Cache::for('checkUser', 'user',DAY_IN_SECONDS); |
| | | return $cache->remember($userId, fn() => (bool) get_userdata($userId)); |
| | | } |
| | | |
| | | protected function checkArray(string $value, array $search, bool $lowercase = true):string|false |
| | | { |
| | | if ($lowercase) { |
| | | $value = strtolower($value); |
| | | } |
| | | |
| | | return in_array($value, $search) ? $value : false; |
| | | |
| | | } |
| | | |
| | | /** |
| | | * Check if term exists (cached) |
| | | */ |
| | |
| | | return false; |
| | | } |
| | | |
| | | $cache = Cache::for('checkTerm', DAY_IN_SECONDS)->connect('taxonomy'); |
| | | $cache = Cache::for('checkTerm', 'term', DAY_IN_SECONDS); |
| | | return $cache->remember($termId, fn() => (bool) term_exists($termId, jvbCheckBase($taxonomy))); |
| | | } |
| | | |
| | |
| | | */ |
| | | protected function isVerifiedUser(int $userId): bool |
| | | { |
| | | $cache = Cache::for('verifiedUsers', DAY_IN_SECONDS)->connect('user'); |
| | | $cache = Cache::for('verifiedUsers', 'user',DAY_IN_SECONDS); |
| | | return $cache->remember($userId, fn() => user_can($userId, 'skip_moderation')); |
| | | } |
| | | |
| | |
| | | return false; |
| | | } |
| | | $post_types = is_array($args['post_type']) ? $args['post_type'] : [$args['post_type']]; |
| | | $hasTimeline = array_map(function($item) { return jvbCheckBase($item); },Registrar::getFeatured('is_timeline', 'post')); |
| | | $hasTimeline = array_map(function($item) { return jvbCheckBase($item); },Registrar::withFeature('is_timeline', 'post')); |
| | | return !empty(array_intersect($post_types, $hasTimeline)); |
| | | } |
| | | // ========================================================================= |
| | |
| | | */ |
| | | protected function verifyTurnstile(string $token): bool |
| | | { |
| | | if (!Site::hasIntegration('cloudflare') || !JVB()->connect('cloudflare')->isSetUp()) { |
| | | if (!Site::hasIntegration('cloudflare') || !Cloudflare::getInstance()->isSetUp()) { |
| | | return true; |
| | | } |
| | | |
| | | return !empty($token) && JVB()->connect('cloudflare')->verifyTurnstile($token); |
| | | return !empty($token) && Cloudflare::getInstance()->verifyTurnstile($token); |
| | | } |
| | | |
| | | /** |
| | |
| | | ]); |
| | | |
| | | try { |
| | | JVB()->error()->log('security_audit', $event, $context, 'info'); |
| | | $this->logError($event,'auditLog', $context); |
| | | } catch (Exception $e) { |
| | | error_log("Security Audit: {$event} - " . json_encode($context)); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Log errors with proper context |
| | | */ |
| | | protected function logError(string $message, array $context = [], string $severity = 'error'): void |
| | | { |
| | | try { |
| | | JVB()->error()->log(static::class, $message, $context, $severity); |
| | | } catch (Exception $e) { |
| | | error_log(static::class . " Error: {$message} - " . json_encode($context)); |
| | | } |
| | | } |
| | | |
| | | /************************************************************ |
| | | SESSION FINGERPRINT |
| | | ************************************************************/ |
| | |
| | | return $terms; |
| | | } |
| | | $ids = array_map('absint', explode(',',$value)); |
| | | $cache = Cache::for('term_data')->connect('taxonomy'); |
| | | $cache = Cache::for('term_data','term'); |
| | | $cache->flush(); |
| | | if (!array_key_exists($taxonomy, $terms)) { |
| | | $terms[$taxonomy] = []; |
| | | $registrar = Registrar::getInstance($taxonomy); |
| | | $terms[$taxonomy]['icon'] = $registrar ? $registrar->getIcon() : jvbDefaultIcon();; |
| | | $terms[$taxonomy]['icon'] = $registrar ? $registrar->getIcon() : jvbDefaultIcon(); |
| | | } |
| | | foreach ($ids as $id) { |
| | | $data = $cache->remember( |
| | |
| | | 'name' => $term->name, |
| | | 'slug' => $term->slug, |
| | | 'parent' => $term->parent, |
| | | 'path' => JVB()->routes('term')->getTermPath($term->term_id, $term->name, $taxonomy), |
| | | 'path' => TermRoutes::getInstance()->getTermPath($term->term_id, $term->name, $taxonomy), |
| | | 'taxonomy' => jvbNoBase($term->taxonomy), |
| | | 'count' => $term->count, |
| | | ]; |