Skip to content

Commit

Permalink
Use WP_REST_Server constants (READABLE, etc) for determing show_in_re…
Browse files Browse the repository at this point in the history
…st status for boxes/fields.
  • Loading branch information
jtsternberg committed Sep 8, 2016
1 parent ad9668a commit 66938b8
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 42 deletions.
2 changes: 1 addition & 1 deletion bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ function cmb2_bootstrap() {
$hookup->universal_hooks();
}

if ( $cmb->prop( 'show_in_rest' ) && function_exists( 'rest_api_init' ) ) {
if ( $cmb->prop( 'show_in_rest' ) && function_exists( 'rest_get_server' ) ) {
$rest = new CMB2_REST( $cmb );
$rest->universal_hooks();
}
Expand Down
2 changes: 1 addition & 1 deletion example-functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ function yourprefix_register_demo_metabox() {
// 'closed' => true, // true to keep the metabox closed by default
// 'classes' => 'extra-class', // Extra cmb2-wrap classes
// 'classes_cb' => 'yourprefix_add_some_classes', // Add classes through a callback.
// 'show_in_rest' => true|'read_and_write'\'write_only', // true to show fields in the WP-API. write is disabled by default. More here: https://github.com/WebDevStudios/CMB2/wiki/REST-API
// 'show_in_rest' => WP_REST_Server::READABLE|WP_REST_Server::ALLMETHODS|WP_REST_Server::EDITABLE, // true to show fields in the WP-API. write is disabled by default. More here: https://github.com/WebDevStudios/CMB2/wiki/REST-API
) );

$cmb_demo->add_field( array(
Expand Down
142 changes: 104 additions & 38 deletions includes/CMB2_REST.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,11 @@ class CMB2_REST extends CMB2_Hookup_Base {
protected $read_fields = array();

/**
* Array of writeable field objects.
* Array of editable field objects.
* @var CMB2_Field[]
* @since 2.2.4
*/
protected $write_fields = array();
protected $edit_fields = array();

/**
* whether CMB2 object is readable via the rest api.
Expand All @@ -60,23 +60,26 @@ class CMB2_REST extends CMB2_Hookup_Base {
protected $rest_read = false;

/**
* whether CMB2 object is writeable via the rest api.
* whether CMB2 object is editable via the rest api.
* @var boolean
*/
protected $rest_write = false;
protected $rest_edit = false;

/**
* Constructor
*
* @since 2.2.4
*
* @param CMB2 $cmb The CMB2 object to be registered for the API.
*/
public function __construct( CMB2 $cmb ) {
$this->cmb = $cmb;
self::$boxes[ $cmb->cmb_id ] = $this;

$show_value = $this->cmb->prop( 'show_in_rest' );
$this->rest_read = 'write_only' !== $show_value;
$this->rest_write = in_array( $show_value, array( 'read_and_write', 'write_only' ), true );

$this->rest_read = self::is_readable( $show_value );
$this->rest_edit = self::is_editable( $show_value );
}

public function universal_hooks() {
Expand All @@ -87,13 +90,13 @@ public function universal_hooks() {
$this->once( 'rest_api_init', array( __CLASS__, 'register_appended_fields' ), 50 );
}

$this->declare_read_write_fields();
$this->declare_read_edit_fields();

add_filter( 'is_protected_meta', array( $this, 'is_protected_meta' ), 10, 3 );
}

public function init_routes() {
global $wp_rest_server;
$wp_rest_server = rest_get_server();

$boxes_controller = new CMB2_REST_Controller_Boxes( $wp_rest_server );
$boxes_controller->register_routes();
Expand Down Expand Up @@ -121,7 +124,7 @@ public static function register_appended_fields() {
);
}

protected function declare_read_write_fields() {
protected function declare_read_edit_fields() {
foreach ( $this->cmb->prop( 'fields' ) as $field ) {
$show_in_rest = isset( $field['show_in_rest'] ) ? $field['show_in_rest'] : null;

Expand All @@ -133,48 +136,59 @@ protected function declare_read_write_fields() {
$this->read_fields[] = $field['id'];
}

if ( $this->can_write( $show_in_rest ) ) {
$this->write_fields[] = $field['id'];
if ( $this->can_edit( $show_in_rest ) ) {
$this->edit_fields[] = $field['id'];
}

}
}

protected function can_read( $show_in_rest ) {
return $this->rest_read
? 'write_only' !== $show_in_rest
: in_array( $show_in_rest, array( 'read_and_write', 'read_only' ), true );
// if 'null', then use default box value.
if ( null === $show_in_rest ) {
return $this->rest_read;
}

// Else check if the value represents readable.
return self::is_readable( $show_in_rest );
}

protected function can_write( $show_in_rest ) {
return $this->rest_write
? 'read_only' !== $show_in_rest
: in_array( $show_in_rest, array( 'read_and_write', 'write_only' ), true );
protected function can_edit( $show_in_rest ) {
// if 'null', then use default box value.
if ( null === $show_in_rest ) {
return $this->rest_edit;
}

// Else check if the value represents editable.
return self::is_editable( $show_in_rest );
}

/**
* Handler for getting custom field data.
*
* @since 2.2.4
* @param array $object The object from the response
* @param string $field_id Name of field
* @param WP_REST_Request $request Current request
*
* @param array $data The data from the response
* @param string $field_name Name of field
* @param WP_REST_Request $request Current request
*
* @return mixed
*/
public static function get_restable_field_values( $object, $field_id, $request ) {
public static function get_restable_field_values( $data, $field_name, $request ) {
$values = array();
if ( ! isset( $object['id'] ) ) {
if ( ! isset( $data['id'] ) ) {
return;
}

foreach ( self::$boxes as $cmb_id => $rest_box ) {
foreach ( $rest_box->read_fields as $field_id ) {
$field = $rest_box->cmb->get_field( $field_id );
$field->object_id( $object['id'] );
$field->object_id( $data['id'] );

// TODO: test other object types (users, comments, etc)
if ( isset( $object->type ) ) {
$field->object_type( $object->type );
}
// if ( isset( $data['type'] ) ) {
// $field->object_type( $data['type'] );
// }

$values[ $cmb_id ][ $field->id( true ) ] = $field->get_data();
}
Expand All @@ -185,14 +199,17 @@ public static function get_restable_field_values( $object, $field_id, $request )

/**
* Handler for updating custom field data.
*
* @since 2.2.4
* @param mixed $value The value of the field
* @param object $object The object from the response
* @param string $field_id Name of field
*
* @param mixed $value The value of the field
* @param object $object The object from the response
* @param string $field_name Name of field
*
* @return bool|int
*/
public static function update_restable_field_values( $values, $object, $field_id ) {
if ( empty( $values ) || ! is_array( $values ) || 'cmb2' !== $field_id ) {
public static function update_restable_field_values( $values, $object, $field_name ) {
if ( empty( $values ) || ! is_array( $values ) || 'cmb2' !== $field_name ) {
return;
}

Expand Down Expand Up @@ -220,7 +237,9 @@ public static function update_restable_field_values( $values, $object, $field_id

/**
* Loop through box fields and sanitize the values.
*
* @since 2.2.o
*
* @param array $values Array of values being provided.
* @return array Array of updated/sanitized values.
*/
Expand All @@ -229,7 +248,7 @@ public function sanitize_box_values( array $values ) {

$this->cmb->pre_process();

foreach ( $this->write_fields as $field_id ) {
foreach ( $this->edit_fields as $field_id ) {
$updated[ $field_id ] = $this->sanitize_field_value( $values, $field_id );
}

Expand All @@ -240,9 +259,12 @@ public function sanitize_box_values( array $values ) {

/**
* Handles returning a sanitized field value.
*
* @since 2.2.4
*
* @param array $values Array of values being provided.
* @param string $field_id The id of the field to update.
*
* @return mixed The results of saving/sanitizing a field value.
*/
protected function sanitize_field_value( array $values, $field_id ) {
Expand All @@ -268,9 +290,12 @@ protected function sanitize_field_value( array $values, $field_id ) {

/**
* Handles returning a sanitized group field value.
*
* @since 2.2.4
*
* @param array $values Array of values being provided.
* @param CMB2_Field $field CMB2_Field object.
*
* @return mixed The results of saving/sanitizing the group field value.
*/
protected function sanitize_group_value( array $values, CMB2_Field $field ) {
Expand All @@ -286,13 +311,15 @@ protected function sanitize_group_value( array $values, CMB2_Field $field ) {

/**
* Filter whether a meta key is protected.
*
* @since 2.2.4
*
* @param bool $protected Whether the key is protected. Default false.
* @param string $meta_key Meta key.
* @param string $meta_type Meta type.
*/
public function is_protected_meta( $protected, $meta_key, $meta_type ) {
if ( $this->field_can_write( $meta_key ) ) {
if ( $this->field_can_edit( $meta_key ) ) {
return false;
}

Expand Down Expand Up @@ -326,8 +353,8 @@ public function field_can_read( $field_id, $return_object = false ) {
return $this->field_can( 'read_fields', $field_id, $return_object );
}

public function field_can_write( $field_id, $return_object = false ) {
return $this->field_can( 'write_fields', $field_id, $return_object );
public function field_can_edit( $field_id, $return_object = false ) {
return $this->field_can( 'edit_fields', $field_id, $return_object );
}

protected function field_can( $type = 'read_fields', $field_id, $return_object = false ) {
Expand All @@ -351,18 +378,57 @@ public static function get_rest_box( $cmb_id ) {
return isset( self::$boxes[ $cmb_id ] ) ? self::$boxes[ $cmb_id ] : false;
}

/**
* Checks if given value is readable.
*
* Value is considered readable if it is not empty and if it does not match the editable blacklist.
*
* @since 2.2.4
*
* @param mixed $value Value to check.
*
* @return boolean Whether value is considered readable.
*/
public static function is_readable( $value ) {
return ! empty( $value ) && ! in_array( $value, array(
WP_REST_Server::CREATABLE,
WP_REST_Server::EDITABLE,
WP_REST_Server::DELETABLE,
), true );
}

/**
* Checks if given value is editable.
*
* Value is considered editable if matches the editable whitelist.
*
* @since 2.2.4
*
* @param mixed $value Value to check.
*
* @return boolean Whether value is considered editable.
*/
public static function is_editable( $value ) {
return in_array( $value, array(
WP_REST_Server::EDITABLE,
WP_REST_Server::ALLMETHODS,
), true );
}

/**
* Magic getter for our object.
*
* @param string $field
* @throws Exception Throws an exception if the field is invalid.
*
* @return mixed
*/
public function __get( $field ) {
switch ( $field ) {
case 'read_fields':
case 'write_fields':
case 'edit_fields':
case 'rest_read':
case 'rest_write':
case 'rest_edit':
return $this->{$field};
default:
throw new Exception( 'Invalid ' . __CLASS__ . ' property: ' . $field );
Expand Down
4 changes: 2 additions & 2 deletions includes/CMB2_REST_Controller_Fields.php
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ public function update_field_value( $request ) {
return $this->prepare_item( array( 'error' => __( 'CMB2 Field value cannot be updated without the value parameter specified.', 'cmb2' ) ) );
}

$field = $this->rest_box->field_can_write( $this->request->get_param( 'field_id' ), true );
$field = $this->rest_box->field_can_edit( $this->request->get_param( 'field_id' ), true );

return $this->modify_field_value( 'updated', $field );
}
Expand All @@ -140,7 +140,7 @@ public function update_field_value( $request ) {
public function delete_field_value( $request ) {
$this->initiate_rest_read_box( $request, 'field_value_delete' );

$field = $this->rest_box->field_can_write( $this->request->get_param( 'field_id' ), true );
$field = $this->rest_box->field_can_edit( $this->request->get_param( 'field_id' ), true );

return $this->modify_field_value( 'deleted', $field );
}
Expand Down

0 comments on commit 66938b8

Please sign in to comment.