Closed gin0115 closed 2 years ago
https://developer.wordpress.org/reference/functions/register_rest_field/
Will need to add options for a get and update callbacks to the Meta_Data model to handle this.
Could use update_post_meta, update_term_meta and get_post_meta, get_term_meta as fallbacks...........with the option to make them nullable by default
Made changes to the follow files as a working prototype.
Meta_Data_Registrar
/** * Registers meta data for a defined type. * * Will cast WP Rest Schema model to array * * @param \PinkCrab\Registerables\Meta_Data $meta * @param string $meta_type The object type ('post', 'user', 'comment', 'term') * @param string $sub_type The object sub-type ('post_type', 'taxonomy') * @return bool * @throws \Exception if fails to register meta data. */ protected function register_meta( Meta_Data $meta, string $meta_type, string $sub_type ): bool { // Clone and set the post type, while enforcing it as a post meta. $meta = clone $meta; $meta->object_subtype( $sub_type ); $meta->meta_type( $meta_type );
// Normalise rest schema model to array.
$meta = $this->normalise_rest_schema( $meta );
$result = register_meta( $meta->get_meta_type(), $meta->get_meta_key(), $meta->parse_args() );
if ( ! $result ) {
throw new \Exception(
"Failed to register {$meta->get_meta_key()} (meta) for {$sub_type} of {$meta_type} type"
);
}
// Maybe register rest fields.
if ( false !== $meta->get_rest_schema() ) {
$this->register_meta_rest( $meta );
}
return $result;
}
/**
@return void */ protected function register_meta_rest( Meta_Data $meta ) { add_action( 'rest_api_init', function () use ( $meta ) { register_rest_field( $meta->get_subtype(), $meta->get_meta_key(), array( 'get_callback' => $meta->get_rest_get() ?? $this->create_rest_get_method( $meta->get_type(), $meta->get_meta_key() ), 'schema' => $meta->get_rest_schema(), 'update_callback' => $meta->get_rest_set(), ), ); } ); }
/**
@return callable */ protected function create_rest_get_method( string $type, string $meta_key ): callable { return function( $object ) use ( $type,$meta_key ) { switch ( $type ) { case 'post': $value = get_post_meta( $object['id'], $meta_key, true ); break;
case 'term':
$value = get_term_meta( $object['id'], $meta_key, true );
break;
case 'user':
$value = get_user_meta( $object['id'], $meta_key, true );
break;
case 'comment':
$value = get_comment_meta( $object['id'], $meta_key, true );
break;
default:
$value = null;
break;
}
return $value;
}; }
> Still needs the UPDATE fallback being created.
FILE :: Meta_Data
/** * The meta fields callbacks * * @var array{ * sanitize: null|callable, * permissions: null|callable, * rest_get: null|callable, * rest_set: null|callable * } */ protected $callbacks = array( 'sanitize' => null, 'permissions' => null, 'rest_get' => null, 'rest_set' => null, );
/**
@return self */ public function rest_get( ?callable $callback ): self { $this->callbacks['rest_get'] = $callback; return $this; }
/**
@return self */ public function rest_set( callable $callback ): self { $this->callbacks['rest_set'] = $callback; return $this; }
/**
@return self */ public function get_rest_get(): ?callable { return $this->callbacks['rest_get']; }
/**
@return self */ public function get_rest_set(): ?callable { return $this->callbacks['rest_set']; }
/**
@return string */ public function get_type(): string { return $this->meta_type; }
/**
Get and Update names need ammedning Update callback generator needs creating
When registering meta data, if the rest schema is defined a matching rest field should created using the same schema