| | |
| | | namespace JVBase\rest\routes; |
| | | |
| | | use JVBase\JVB; |
| | | use JVBase\rest\RestRouteManager; |
| | | use JVBase\meta\MetaManager; |
| | | use JVBase\managers\Cache; |
| | | use JVBase\managers\IconsManager; |
| | | use JVBase\rest\Rest; |
| | | use JVBase\rest\Route; |
| | | use JVBase\rest\PermissionHandler; |
| | | use WP_Query; |
| | | use WP_Error; |
| | | use WP_REST_Request; |
| | |
| | | exit; // Exit if accessed directly |
| | | } |
| | | |
| | | class AdminRoutes extends RestRouteManager |
| | | class AdminRoutes extends Rest |
| | | { |
| | | protected array $fields; |
| | | protected $meta; |
| | |
| | | |
| | | public function __construct() |
| | | { |
| | | $this->cache_name = 'itsme'; |
| | | $this->cacheName = 'itsme'; |
| | | parent::__construct(); |
| | | $this->action = 'itsme'; |
| | | } |
| | | public function registerRoutes():void |
| | | { |
| | | if (!current_user_can('manage_options')) { |
| | | return; |
| | | } |
| | | register_rest_route($this->namespace, '/myster', [ |
| | | [ |
| | | 'methods' => 'GET', |
| | | 'callback' => [$this, 'getItems'], |
| | | 'permission_callback' => [$this, 'checkPermission'] |
| | | ], |
| | | [ |
| | | 'methods' => 'POST', |
| | | 'callback' => [$this, 'updateItems'], |
| | | 'permission_callback' => [$this, 'checkPermission'] |
| | | ] |
| | | ]); |
| | | Route::for('admin-cache') |
| | | ->post([$this, 'handleCacheAction']) |
| | | ->auth('admin') |
| | | ->rateLimit(30) |
| | | ->register(); |
| | | |
| | | register_rest_route($this->namespace, '/admin-action', [ |
| | | [ |
| | | 'methods' => 'POST', |
| | | 'callback' => [$this, 'adminAction'], |
| | | 'permission_callback' => [$this, 'checkPermission'] |
| | | ] |
| | | ]); |
| | | } |
| | | Route::for('admin-icons') |
| | | ->post([$this, 'handleIconAction']) |
| | | ->auth('admin') |
| | | ->rateLimit(30) |
| | | ->register(); |
| | | |
| | | /** |
| | | * @param WP_REST_Request $request The Request object |
| | | * |
| | | * @return bool whether or not we can proceed |
| | | */ |
| | | public function checkPermission(WP_REST_Request $request):bool |
| | | { |
| | | if (!current_user_can('manage_options')) { |
| | | return false; |
| | | } |
| | | $this->verifyNonce($request, 'wp_rest'); |
| | | if ($this->action!=='') { |
| | | $this->verifyNonce($request, $this->action . get_current_user_id(), $request->get_header('action_nonce')); |
| | | } |
| | | return true; |
| | | Route::for('admin-action') |
| | | ->post([$this, 'adminAction']) |
| | | ->auth('admin') |
| | | ->rateLimit() |
| | | ->register(); |
| | | } |
| | | |
| | | /** |
| | |
| | | ); |
| | | } |
| | | |
| | | /** |
| | | * @param WP_REST_Request $request Request object |
| | | * |
| | | * @return WP_REST_Response |
| | | */ |
| | | public function updateItems(WP_REST_Request $request):WP_REST_Response |
| | | { |
| | | error_log('Received Request: '.print_r($request->get_params(), true)); |
| | | $content = $request->get_param('content'); |
| | | if (!$this->checkContent($content, true)) { |
| | | return new WP_REST_Response([ |
| | | 'sucess' => false, |
| | | 'message' => 'Invalid attempt' |
| | | ]); |
| | | } |
| | | $data = $request->get_param('data'); |
| | | if (empty($data)) { |
| | | return new WP_REST_Response([ |
| | | 'success' => true, |
| | | 'message' => 'Nothing to Update' |
| | | ]); |
| | | } |
| | | |
| | | $type = match ($content) { |
| | | 'shop', |
| | | 'artform', |
| | | 'type', |
| | | 'media', |
| | | 'artstyle', |
| | | 'arttheme', |
| | | 'city', |
| | | 'colour', |
| | | 'offerfor', |
| | | 'pstyle', |
| | | 'style', |
| | | 'theme' => 'term', |
| | | default => 'post', |
| | | }; |
| | | $errors = []; |
| | | $success = []; |
| | | error_log('Data: '.print_r($data, true)); |
| | | |
| | | foreach ($data as $ID => $fields) { |
| | | $ID = (int)$ID; |
| | | $meta = new MetaManager($ID, $type); |
| | | $allFields = JVB()->getFields($content); |
| | | foreach ($fields as $name => $value) { |
| | | $process = true; |
| | | if (!array_key_exists($name, $allFields)) { |
| | | $errors[$ID][$name] = __('Field not found', 'jvb'); |
| | | $process = false; |
| | | } |
| | | error_log('Proceeding as Normal...'); |
| | | //Switch between config types to extract values for special cases |
| | | $config = $allFields[$name]; |
| | | |
| | | switch ($config['type']) { |
| | | case 'radio': |
| | | //Ensure we only chose one option |
| | | $temp = explode(',', $value); |
| | | $value = trim($temp[0]); |
| | | if (!in_array($value, $config['options'])) { |
| | | $errors[$ID][$name] = __('Invalid Option', 'jvb'); |
| | | $process = false; |
| | | } |
| | | break; |
| | | case 'set': |
| | | $temp = explode(',', $value); |
| | | $value = array_map('trim', $temp); |
| | | break; |
| | | case 'repeater': |
| | | error_log('Repeater: '.print_r($name, true)); |
| | | $single = false; |
| | | switch ($name) { |
| | | case 'keywords': |
| | | $single = 'keyword'; |
| | | break; |
| | | case 'languages': |
| | | $single = 'language'; |
| | | break; |
| | | case 'links': |
| | | $single = 'url'; |
| | | break; |
| | | case 'followers': |
| | | $single = 'count'; |
| | | break; |
| | | } |
| | | $items = array_keys($config['fields']); |
| | | |
| | | //First, separate out any ] |
| | | if (strpos($value, ']')) { |
| | | $rows = array_map(function ($item) { |
| | | return str_replace('[', '', $item); |
| | | }, explode(']', $value)); |
| | | array_pop($rows); |
| | | error_log('Rows: '.print_r($rows, true)); |
| | | $value = []; |
| | | foreach ($rows as $index => $row) { |
| | | $r = array_map('trim', explode(',', $row)); |
| | | if (count($r) !== count($items)) { |
| | | $errors[$ID][$name] = __('Not enough fields set. May not save correctly', 'jvb'); |
| | | } |
| | | //attempt to save fields |
| | | $new = []; |
| | | foreach ($items as $key => $i) { |
| | | $new[$i] = (array_key_exists($key, $r)) ? $r[$key] : (($i==='checked') ? date('Y-m-d'): ''); |
| | | } |
| | | $value[] = $new; |
| | | } |
| | | error_log('Processed Repeater Value for sanitizing: '.print_r($value, true)); |
| | | |
| | | } elseif ($value === '') { |
| | | $value = []; |
| | | } else { |
| | | if (!$single) { |
| | | $errors[$ID][$name] = __('Must set single key', 'jvb'); |
| | | $process = false; |
| | | } |
| | | $rows = array_map('trim', explode(',', $value)); |
| | | $value = []; |
| | | foreach ($rows as $row) { |
| | | $new = []; |
| | | foreach ($items as $i) { |
| | | $new[$i] = ($i === $single) ? $row : (($i==='checked') ? date('Y-m-d') : ''); |
| | | } |
| | | error_log('New Repeater Row Output: '.print_r($new, true)); |
| | | $value[] = $new; |
| | | } |
| | | } |
| | | |
| | | break; |
| | | } |
| | | |
| | | switch ($name) { |
| | | case 'shop': |
| | | case 'type': |
| | | case 'city': |
| | | $terms = array_map('trim', explode(',', $value)); |
| | | $set = []; |
| | | foreach ($terms as $term) { |
| | | $t = get_term_by('name', $value, BASE.$name); |
| | | if (!$t) { |
| | | $errors[$ID][$name][] = __($value.' does not exist yet', 'jvb'); |
| | | } else { |
| | | $set[] = $t->term_id; |
| | | } |
| | | } |
| | | if (!empty($set)) { |
| | | $result = wp_set_post_terms($ID, $set, BASE.$name); |
| | | $result = is_array($result); |
| | | } |
| | | break; |
| | | case 'owner': |
| | | error_log('Processing Owner Request from Admin Routes...'); |
| | | $users = array_map('trim', explode(',', $value)); |
| | | foreach ($users as $user) { |
| | | $t = jvbGetUserByDisplayName($user)??jvbGetUserByFirstName($user)??false; |
| | | error_log('Got user: '.print_r($t, true)); |
| | | if (!$t) { |
| | | $errors[$ID][$name][] = __($value.' does not exist yet...', 'jvb'); |
| | | $result = false; |
| | | } else { |
| | | $result = JVB()->routes('shop')->setShopOwner($t->ID, $ID, true); |
| | | } |
| | | } |
| | | break; |
| | | case 'managers': |
| | | error_log('Processing Manager Request from Admin Routes...'); |
| | | $users = array_map('trim', explode(',', $value)); |
| | | foreach ($users as $user) { |
| | | $t = jvbGetUserByDisplayName($user)??jvbGetUserByFirstName($user)??false; |
| | | error_log('Got user: '.print_r($t, true)); |
| | | if (!$t) { |
| | | $result = $errors[$ID][$name][] = __($value.' does not exist yet...', 'jvb'); |
| | | } else { |
| | | $result = JVB()->routes('shop')->setShopManager($t->ID, $ID, true); |
| | | } |
| | | } |
| | | break; |
| | | case 'location': |
| | | $value = [ |
| | | 'address' => $value, |
| | | 'lat' => '', |
| | | 'lng' => '', |
| | | ]; |
| | | $result = $meta->updateValue($name, $value); |
| | | break; |
| | | case 'hours': |
| | | $temp = []; |
| | | foreach ($value as $key => $v) { |
| | | if (strpos($v['days'], '-')) { |
| | | $temp[$key]['days'] = jvbExpandDayRange($v['days']); |
| | | $temp[$key]['time_open'] = $v['time_open']; |
| | | $temp[$key]['time_closes'] = $v['time_closes']; |
| | | } |
| | | } |
| | | $value = $temp; |
| | | error_log('Final Hours for processing: '.print_r($value, true)); |
| | | $result = $meta->updateValue($name, $value); |
| | | break; |
| | | default: |
| | | $result = $meta->updateValue($name, $value); |
| | | break; |
| | | } |
| | | |
| | | //Save the value |
| | | if ($result) { |
| | | $success[$ID][] = $name; |
| | | } else { |
| | | $errors[$ID][] = [ |
| | | $name => 'Could not update value' |
| | | ]; |
| | | } |
| | | } |
| | | } |
| | | return new WP_REST_Response([ |
| | | 'success' => true, |
| | | 'successful' => $success, |
| | | 'errors' => $errors |
| | | ]); |
| | | } |
| | | |
| | | /** |
| | | * @param array $filters |
| | |
| | | return $out; |
| | | } |
| | | |
| | | /** |
| | | * @param WP_REST_Request $request The REST Request |
| | | * |
| | | * @return array |
| | | */ |
| | | protected function buildParams(WP_REST_Request $request):array |
| | | { |
| | | $data = $request->get_params(); |
| | | $this->setMetaType($data['content']); |
| | | switch ($this->metaType) { |
| | | case 'post': |
| | | $key = 'post_type'; |
| | | break; |
| | | case 'term': |
| | | $key = 'taxonomy'; |
| | | break; |
| | | case 'user': |
| | | $key = 'role'; |
| | | break; |
| | | default: |
| | | return []; |
| | | } |
| | | global $jvb_everything; |
| | | return [ |
| | | $key => (array_key_exists('content', $data) && |
| | | array_key_exists($data['content'], $jvb_everything)) ? |
| | | BASE.$data['content'] : BASE.'artist', |
| | | 'order' => (array_key_exists('order', $data) && |
| | | in_array(strtolower($data['order']), ['asc', 'desc'])) ? |
| | | strtolower($data['order']) : 'desc', |
| | | 'orderby' => (array_key_exists('orderby', $data) && |
| | | in_array($data['orderby'], ['name', 'date', 'followers', 'karma'])) ? |
| | | $data['orderby'] : 'name', |
| | | 'paged' => (array_key_exists('page', $data) && is_numeric($data['page'])) ? |
| | | (int)$data['page'] : 1, |
| | | 'filters' => (array_key_exists('filters', $data)) ? |
| | | $this->checkFilters($data['filters']) : null, |
| | | ]; |
| | | } |
| | | /** |
| | | * Handle cache-related actions |
| | | */ |
| | | public function handleCacheAction(\WP_REST_Request $request): \WP_REST_Response |
| | | { |
| | | $action = sanitize_text_field($request->get_param('action')); |
| | | |
| | | protected function setMetaType(string $type):void |
| | | { |
| | | $this->metaType = match (true) { |
| | | array_key_exists($type, JVB_CONTENT) => 'post', |
| | | array_key_exists($type, JVB_TAXONOMY) => 'term', |
| | | array_key_exists($type, JVB_USER) => 'user', |
| | | default => false, |
| | | }; |
| | | } |
| | | switch ($action) { |
| | | case 'flush-all': |
| | | $total = Cache::flushAll(); |
| | | return new \WP_REST_Response([ |
| | | 'success' => true, |
| | | 'message' => $total.' caches flushed successfully' |
| | | ]); |
| | | |
| | | /** |
| | | * @param WP_REST_Request $request The REST Request |
| | | * |
| | | * @return WP_REST_Response |
| | | */ |
| | | public function getItems(WP_REST_Request $request):WP_REST_Response |
| | | { |
| | | case 'flush-cache': |
| | | $group = sanitize_text_field($request->get_param('group')); |
| | | if (empty($group)) { |
| | | return new \WP_REST_Response([ |
| | | 'success' => false, |
| | | 'message' => 'No cache group specified' |
| | | ], 400); |
| | | } |
| | | |
| | | $args = $this->buildParams($request); |
| | | $key = $this->cache->generateKey($args); |
| | | Cache::for($group)?->flush(); |
| | | |
| | | $cache = $this->cache->get($key); |
| | | if ($cache) { |
| | | return new WP_REST_Response($cache); |
| | | } |
| | | return new \WP_REST_Response([ |
| | | 'success' => true, |
| | | 'message' => "Cache group '{$group}' flushed successfully" |
| | | ]); |
| | | |
| | | $this->content = $request->get_param('content'); |
| | | $args['posts_per_page'] = 50; |
| | | |
| | | $this->fields = jvbGetFields($this->content); |
| | | // $this->fields = array_filter(JVB()->getFields($data['content']), function($arr){ |
| | | // return array_key_exists('quickEdit', $arr); |
| | | // }); |
| | | |
| | | $response = match ($this->metaType) { |
| | | 'post' => $this->getPostItems($args), |
| | | 'term' => $this->getTermItems($args), |
| | | 'user' => $this->getUserItems($args), |
| | | default => [] |
| | | }; |
| | | |
| | | $this->cache->set($key, $response); |
| | | return new WP_REST_Response($response); |
| | | } |
| | | |
| | | /** |
| | | * @param array $args the data from buildParams method |
| | | * |
| | | * @return array |
| | | */ |
| | | protected function getTermItems(array $args):array |
| | | { |
| | | if (isJVBContentTax($args['taxonomy'])) { |
| | | return $this->getContentTypeTaxItems($args); |
| | | default: |
| | | return new \WP_REST_Response([ |
| | | 'success' => false, |
| | | 'message' => 'Invalid action' |
| | | ], 400); |
| | | } |
| | | // Build query arguments |
| | | $args = array_merge($args, [ |
| | | 'hide_empty' => false, |
| | | 'number' => $args['posts_per_page'], |
| | | 'offset' => ($args['paged'] - 1) * $args['posts_per_page'], |
| | | 'fields' => 'ids' |
| | | ]); |
| | | } |
| | | |
| | | // Add ordering |
| | | switch ($args['orderby']) { |
| | | case 'date': |
| | | $args['orderby'] = 'id'; // Terms don't have date, so use ID as a proxy |
| | | break; |
| | | case 'karma': |
| | | // Terms should be ordered by meta value |
| | | $args['orderby'] = 'meta_value_num'; |
| | | $args['meta_key'] = BASE . 'karma'; |
| | | break; |
| | | default: |
| | | $args['orderby'] = 'name'; |
| | | break; |
| | | } |
| | | $args['order'] = strtoupper($args['order']); |
| | | /** |
| | | * Handle icon-related actions |
| | | */ |
| | | public function handleIconAction(\WP_REST_Request $request): \WP_REST_Response |
| | | { |
| | | $action = sanitize_text_field($request->get_param('action')); |
| | | $source = sanitize_text_field($request->get_param('source') ?? 'icons'); |
| | | $icons = IconsManager::for($source); |
| | | |
| | | // Add any filters |
| | | if (!empty($args['filters'])) { |
| | | // Term meta filtering would go here |
| | | $meta_query = []; |
| | | switch ($action) { |
| | | case 'refresh-icons': |
| | | // Force regenerate CSS immediately |
| | | $icons->forceRefresh(); |
| | | IconsManager::regenerateAllCSS([$source => true]); |
| | | |
| | | foreach ($args['filters'] as $filter_type => $filter_values) { |
| | | if (!empty($filter_values)) { |
| | | // Example: filter by parent terms |
| | | if ($filter_type === 'parent') { |
| | | $args['parent'] = $filter_values[0]; // Assume single parent filter |
| | | } else { |
| | | // For meta-based filters |
| | | $meta_query[] = [ |
| | | 'key' => BASE . $filter_type, |
| | | 'value' => $filter_values, |
| | | 'compare' => 'IN' |
| | | ]; |
| | | } |
| | | } |
| | | } |
| | | return new \WP_REST_Response([ |
| | | 'success' => true, |
| | | 'message' => "Icon CSS regenerated successfully for '{$source}'" |
| | | ]); |
| | | |
| | | if (!empty($meta_query)) { |
| | | $args['meta_query'] = $meta_query; |
| | | } |
| | | } |
| | | unset($args['filters']); |
| | | case 'refresh-all-icons': |
| | | // Regenerate all icon sources |
| | | foreach (['icons', 'forms', 'dash'] as $src) { |
| | | IconsManager::for($src)->forceRefresh(); |
| | | } |
| | | IconsManager::regenerateAllCSS(); |
| | | |
| | | // Get count first for pagination info |
| | | $count_args = $args; |
| | | unset($count_args['number']); |
| | | unset($count_args['offset']); |
| | | $count_args['fields'] = 'count'; |
| | | $total_items = get_terms($count_args); |
| | | return new \WP_REST_Response([ |
| | | 'success' => true, |
| | | 'message' => 'All icon CSS files regenerated successfully' |
| | | ]); |
| | | |
| | | // Get the actual terms |
| | | $term_ids = get_terms($args); |
| | | case 'restore-icon-version': |
| | | $timestamp = (int)$request->get_param('timestamp'); |
| | | if (empty($timestamp)) { |
| | | return new \WP_REST_Response([ |
| | | 'success' => false, |
| | | 'message' => 'No timestamp provided' |
| | | ], 400); |
| | | } |
| | | |
| | | // Error handling |
| | | if (is_wp_error($term_ids)) { |
| | | return [ |
| | | 'items' => [], |
| | | 'has_more' => false, |
| | | 'total_items' => 0, |
| | | 'total_pages' => 0, |
| | | 'error' => $term_ids->get_error_message() |
| | | ]; |
| | | } |
| | | if ($icons->restoreVersion($timestamp)) { |
| | | return new \WP_REST_Response([ |
| | | 'success' => true, |
| | | 'message' => 'Icon version restored successfully' |
| | | ]); |
| | | } |
| | | |
| | | // Format each term |
| | | $items = array_map([$this, 'formatItem'], $term_ids); |
| | | return new \WP_REST_Response([ |
| | | 'success' => false, |
| | | 'message' => 'Failed to restore icon version' |
| | | ], 500); |
| | | |
| | | return [ |
| | | 'items' => $items, |
| | | 'has_more' => ($total_items > ($args['offset'] + $args['number'])), |
| | | 'total_items' => (int)$total_items, |
| | | 'total_pages' => ceil($total_items / $args['posts_per_page']) |
| | | ]; |
| | | } |
| | | case 'merge-icon-versions': |
| | | $timestamps = $request->get_param('timestamps'); |
| | | |
| | | protected function getUserItems(array $args):array |
| | | { |
| | | return []; |
| | | } |
| | | if (empty($timestamps) || !is_array($timestamps)) { |
| | | return new \WP_REST_Response([ |
| | | 'success' => false, |
| | | 'message' => 'No versions selected for merging' |
| | | ], 400); |
| | | } |
| | | |
| | | /** |
| | | * @param array $data the $data built by buildParams |
| | | * |
| | | * @return array |
| | | */ |
| | | protected function getContentTypeTaxItems(array $data):array |
| | | { |
| | | global $wpdb; |
| | | $table_name = $wpdb->prefix . BASE . jvbNoBase($data['taxonomy']); |
| | | $timestamps = array_map('intval', $timestamps); |
| | | |
| | | // Start building the query to get just the term_ids with proper ordering |
| | | $sql_select = "SELECT s.term_id"; |
| | | $sql_from = " FROM {$table_name} AS s"; |
| | | $sql_where = " WHERE 1=1"; |
| | | $sql_orderby = ""; |
| | | $sql_limit = ""; |
| | | if (count($timestamps) < 2) { |
| | | return new \WP_REST_Response([ |
| | | 'success' => false, |
| | | 'message' => 'Please select at least 2 versions to merge' |
| | | ], 400); |
| | | } |
| | | |
| | | $params = []; |
| | | if ($icons->mergeVersions($timestamps)) { |
| | | // Regenerate CSS after merge |
| | | IconsManager::regenerateAllCSS([$source => true]); |
| | | |
| | | // Add filters if any |
| | | if (!empty($data['filters'])) { |
| | | foreach ($data['filters'] as $filter_type => $filter_values) { |
| | | if ($filter_type === 'city' && !empty($filter_values)) { |
| | | $placeholders = implode(',', array_fill(0, count($filter_values), '%d')); |
| | | $sql_where .= $wpdb->prepare(" AND s.city IN ($placeholders)", ...$filter_values); |
| | | } |
| | | // Add more filter conditions for other fields as needed |
| | | } |
| | | } |
| | | return new \WP_REST_Response([ |
| | | 'success' => true, |
| | | 'message' => 'Icon versions merged successfully' |
| | | ]); |
| | | } |
| | | |
| | | // Determine ORDER BY clause - here we can use any column from the custom table |
| | | $valid_order_columns = ['name', 'updated_at', 'established_year', 'karma']; |
| | | $orderby_column = in_array($data['orderby'], $valid_order_columns) ? $data['orderby'] : 'name'; |
| | | $sql_orderby = " ORDER BY s." . $orderby_column; |
| | | return new \WP_REST_Response([ |
| | | 'success' => false, |
| | | 'message' => 'Failed to merge icon versions' |
| | | ], 500); |
| | | |
| | | // Validate order direction |
| | | $order_direction = strtoupper($data['order']) === 'DESC' ? 'DESC' : 'ASC'; |
| | | $sql_orderby .= " " . $order_direction; |
| | | |
| | | // Calculate offset for pagination |
| | | $per_page = absint($data['posts_per_page']); |
| | | $page = max(1, absint($data['paged'])); |
| | | $offset = ($page - 1) * $per_page; |
| | | |
| | | // Add pagination with prepared statement |
| | | $sql_limit = $wpdb->prepare(" LIMIT %d OFFSET %d", $per_page, $offset); |
| | | |
| | | // Count query (without limit clause) |
| | | $count_sql = "SELECT COUNT(s.term_id)" . $sql_from . $sql_where; |
| | | $total_items = $wpdb->get_var($count_sql); |
| | | |
| | | // Final query with all components |
| | | $sql = $sql_select . $sql_from . $sql_where . $sql_orderby . $sql_limit; |
| | | |
| | | // Execute the query |
| | | $shop_term_ids = $wpdb->get_col($sql); |
| | | |
| | | // Now get the full term objects for these IDs |
| | | $items = []; |
| | | foreach ($shop_term_ids as $shop_term_id) { |
| | | $items[] = $this->formatItem($shop_term_id); |
| | | } |
| | | |
| | | return [ |
| | | 'items' => $items, |
| | | 'has_more' => ($total_items > ($offset + $per_page)), |
| | | 'total_items' => (int)$total_items, |
| | | 'total_pages' => ceil($total_items / $per_page) |
| | | ]; |
| | | } |
| | | |
| | | /** |
| | | * @param array $args array returned by buildParams |
| | | * |
| | | * @return array |
| | | */ |
| | | protected function getPostItems(array $args):array |
| | | { |
| | | $args['fields'] = 'ids'; |
| | | $args['post_status'] = ['draft', 'trash', 'publish']; |
| | | |
| | | $query = new WP_Query($args); |
| | | $items = array_map([$this, 'formatItem'], $query->posts); |
| | | |
| | | return [ |
| | | 'items' => $items, |
| | | 'has_more' => $query->max_num_pages > $args['paged'], |
| | | 'total_items' => $query->found_posts, |
| | | 'total_pages' => $query->max_num_pages |
| | | ]; |
| | | } |
| | | |
| | | /** |
| | | * @param int $ID the ID of the item to format |
| | | * |
| | | * @return array |
| | | */ |
| | | protected function formatItem(int $ID):array |
| | | { |
| | | $meta = new MetaManager($ID, $this->metaType); |
| | | $item = [ |
| | | 'id' => $ID, |
| | | 'public' => !($this->metaType === 'post') || get_post_status($ID) === 'publish', |
| | | ]; |
| | | |
| | | $hierarchical = false; |
| | | if ($this->metaType === 'term') { |
| | | $term = get_term($ID); |
| | | if ($term) { |
| | | $hierarchical = is_taxonomy_hierarchical($term->taxonomy); |
| | | } |
| | | } |
| | | |
| | | foreach ($this->fields as $key => $config) { |
| | | switch ($key) { |
| | | case 'type': |
| | | case 'city': |
| | | case 'shop': |
| | | $terms = get_the_terms($ID, BASE.$key); |
| | | $value = []; |
| | | if ($terms && !is_wp_error($terms)) { |
| | | foreach ($terms as $term) { |
| | | $value[] = htmlspecialchars_decode($term->name); |
| | | } |
| | | } |
| | | $item[$key] = implode(', ', $value); |
| | | break; |
| | | default: |
| | | $item[$key] = $meta->getValue($key); |
| | | break; |
| | | } |
| | | |
| | | switch ($config['type']) { |
| | | case 'repeater': |
| | | if (empty($item[$key]) || !is_array($item[$key])) { |
| | | $item[$key] = ''; |
| | | } else { |
| | | $temp = ''; |
| | | foreach ($item[$key] as $row) { |
| | | if (is_array($row)) { |
| | | // Format each row as [value1,value2,value3] |
| | | $rowValues = array_values($row); |
| | | $temp .= '[' . implode(',', $rowValues) . ']'; |
| | | } else { |
| | | // Handle simpler cases where rows might not be arrays |
| | | $temp .= '[' . $row . ']'; |
| | | } |
| | | } |
| | | $item[$key] = $temp; |
| | | } |
| | | break; |
| | | case 'location': |
| | | $item[$key] = $item[$key]['address']; |
| | | break; |
| | | } |
| | | if ($hierarchical && $key === 'term_name') { |
| | | $item[$key.'_path'] = JVB()->routes('term')->getTermPath($ID, html_entity_decode($term->name), $term->taxonomy); |
| | | } |
| | | } |
| | | |
| | | error_log('Item: '.print_r($item, true)); |
| | | return $item; |
| | | } |
| | | default: |
| | | return new \WP_REST_Response([ |
| | | 'success' => false, |
| | | 'message' => 'Invalid action' |
| | | ], 400); |
| | | } |
| | | } |
| | | } |