Advertisement
JoachimBrnd

Voxel API exposer (Joachim Brindeau)

Aug 23rd, 2024 (edited)
278
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 6.62 KB | Software | 0 0
  1. <?php
  2. add_action('init', 'expose_voxel_cpts_to_rest_api', 99);
  3. add_action('rest_api_init', 'register_custom_fields_in_rest_api', 15);
  4.  
  5. function expose_voxel_cpts_to_rest_api() {
  6.     $voxel_post_types = json_decode(get_option('voxel:post_types'), true) ?: [];
  7.     foreach ($voxel_post_types as $post_type => $post_type_data) {
  8.         if (!in_array($post_type, ['post', 'page'])) {
  9.             $obj = get_post_type_object($post_type);
  10.             if ($obj) {
  11.                 $obj->show_in_rest = true;
  12.                 $obj->rest_base = $post_type;
  13.                 $obj->rest_controller_class = 'WP_REST_Posts_Controller';
  14.             }
  15.         }
  16.     }
  17. }
  18.  
  19. function register_custom_fields_in_rest_api() {
  20.     $voxel_post_types = json_decode(get_option('voxel:post_types'), true) ?: [];
  21.     foreach ($voxel_post_types as $post_type => $post_type_data) {
  22.         if (isset($post_type_data['fields'])) {
  23.             foreach ($post_type_data['fields'] as $field) {
  24.                 if (in_array($field['type'], ['ui-step', 'title'])) continue;
  25.                
  26.                 register_rest_field($post_type, $field['key'], [
  27.                     'get_callback' => function($post_arr) use ($field) {
  28.                         return get_custom_field_value($post_arr['id'], $field);
  29.                     },
  30.                     'update_callback' => function($value, $post, $field_name) use ($field) {
  31.                         return update_custom_field_value($post->ID, $field, $value);
  32.                     },
  33.                     'schema' => [
  34.                         'description' => $field['label'],
  35.                         'type'        => get_schema_type_for_field($field['type']),
  36.                         'context'     => ['view', 'edit'],
  37.                     ],
  38.                 ]);
  39.  
  40.                 if ($field['type'] === 'post-relation') {
  41.                     $relation_field_name = get_relation_field_name($field);
  42.                     register_rest_field($post_type, $relation_field_name, [
  43.                         'get_callback' => function($post_arr) use ($field) {
  44.                             return get_post_relation_value($post_arr['id'], $field['key']);
  45.                         },
  46.                         'update_callback' => function($value, $post, $field_name) use ($field) {
  47.                             return update_post_relation_value($post->ID, $field['key'], $value);
  48.                         },
  49.                         'schema' => [
  50.                             'description' => $field['label'] . ' (FK)',
  51.                             'type'        => 'array',
  52.                             'items'       => ['type' => 'integer'],
  53.                             'context'     => ['view', 'edit'],
  54.                         ],
  55.                     ]);
  56.                 }
  57.             }
  58.         }
  59.     }
  60. }
  61.  
  62. function get_relation_field_name($field) {
  63.     $related_post_type = $field['post_types'][0] ?? 'post';
  64.     $related_post_type = ($related_post_type === 'page') ? 'pages' : $related_post_type;
  65.     $related_post_type = ($related_post_type === 'post') ? 'posts' : $related_post_type;
  66.     return $field['key'] . '_fk_' . $related_post_type;
  67. }
  68.  
  69. function get_custom_field_value($post_id, $field) {
  70.     $value = get_post_meta($post_id, $field['key'], true);
  71.  
  72.     switch ($field['type']) {
  73.         case 'repeater':
  74.             $repeater_values = [];
  75.             if (is_array($value)) {
  76.                 foreach ($value as $index => $repeater_item) {
  77.                     $repeater_values[$index] = [];
  78.                     foreach ($field['fields'] as $sub_field) {
  79.                         $sub_key = $field['key'] . '_' . $index . '_' . $sub_field['key'];
  80.                         $repeater_values[$index][$sub_field['key']] = get_post_meta($post_id, $sub_key, true);
  81.                     }
  82.                 }
  83.             }
  84.             return $repeater_values;
  85.         case 'post-relation':
  86.             return null; // We'll handle this separately
  87.         case 'image':
  88.         case 'file':
  89.             return (int) $value;
  90.         case 'location':
  91.             return maybe_unserialize($value);
  92.         default:
  93.             return $value;
  94.     }
  95. }
  96.  
  97. function update_custom_field_value($post_id, $field, $value) {
  98.     switch ($field['type']) {
  99.         case 'repeater':
  100.             if (is_array($value)) {
  101.                 delete_post_meta($post_id, $field['key']);
  102.                 foreach ($value as $index => $repeater_item) {
  103.                     foreach ($field['fields'] as $sub_field) {
  104.                         if (isset($repeater_item[$sub_field['key']])) {
  105.                             $sub_key = $field['key'] . '_' . $index . '_' . $sub_field['key'];
  106.                             update_post_meta($post_id, $sub_key, $repeater_item[$sub_field['key']]);
  107.                         }
  108.                     }
  109.                 }
  110.                 update_post_meta($post_id, $field['key'], array_keys($value));
  111.             }
  112.             break;
  113.         case 'post-relation':
  114.             // We'll handle this separately
  115.             break;
  116.         case 'location':
  117.             update_post_meta($post_id, $field['key'], maybe_serialize($value));
  118.             break;
  119.         default:
  120.             update_post_meta($post_id, $field['key'], $value);
  121.     }
  122.     return true;
  123. }
  124.  
  125. function get_schema_type_for_field($field_type) {
  126.     switch ($field_type) {
  127.         case 'number':
  128.         case 'switcher':
  129.             return 'number';
  130.         case 'image':
  131.         case 'file':
  132.             return 'integer';
  133.         case 'post-relation':
  134.         case 'repeater':
  135.             return 'array';
  136.         case 'select':
  137.             return ['string', 'array'];
  138.         case 'location':
  139.             return 'object';
  140.         default:
  141.             return 'string';
  142.     }
  143. }
  144.  
  145. function get_post_relation_value($post_id, $relation_key) {
  146.     global $wpdb;
  147.     $child_ids = $wpdb->get_col($wpdb->prepare(
  148.         "SELECT child_id FROM {$wpdb->prefix}voxel_relations WHERE parent_id = %d AND relation_key = %s",
  149.         $post_id,
  150.         $relation_key
  151.     ));
  152.     return array_map('intval', $child_ids);
  153. }
  154.  
  155. function update_post_relation_value($post_id, $relation_key, $child_ids) {
  156.     global $wpdb;
  157.     $wpdb->delete("{$wpdb->prefix}voxel_relations", [
  158.         'parent_id' => $post_id,
  159.         'relation_key' => $relation_key,
  160.     ]);
  161.     if (is_array($child_ids)) {
  162.         foreach ($child_ids as $child_id) {
  163.             $wpdb->insert("{$wpdb->prefix}voxel_relations", [
  164.                 'parent_id' => $post_id,
  165.                 'child_id' => (int) $child_id,
  166.                 'relation_key' => $relation_key,
  167.             ]);
  168.         }
  169.     }
  170.     return true;
  171. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement