Skip to content

Commit

Permalink
Merge branch 'development'
Browse files Browse the repository at this point in the history
  • Loading branch information
vvasilev- committed Feb 27, 2019
2 parents 1e55302 + 5f876e3 commit cedc8b2
Show file tree
Hide file tree
Showing 15 changed files with 541 additions and 27 deletions.
1 change: 1 addition & 0 deletions bin/webpack.blocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ module.exports = [
'react-dom': [ 'cf', 'vendor', 'react-dom' ],
'nanoid': [ 'cf', 'vendor', 'nanoid' ],
'immer': [ 'cf', 'vendor', 'immer' ],
'@wordpress/api-fetch': [ 'wp', 'apiFetch' ],
'@wordpress/components': [ 'wp', 'components' ],
'@wordpress/blocks': [ 'wp', 'blocks' ],
'@wordpress/editor': [ 'wp', 'editor' ],
Expand Down
2 changes: 1 addition & 1 deletion config.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

# Define version constant
if ( ! defined( __NAMESPACE__ . '\VERSION' ) ) {
define( __NAMESPACE__ . '\VERSION', '3.0.2' );
define( __NAMESPACE__ . '\VERSION', '3.1.0-beta.1' );
}

# Define root directory
Expand Down
140 changes: 136 additions & 4 deletions core/Container/Block_Container.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ class Block_Container extends Container {
*/
public $settings = array(
'preview' => true,
'parent' => null,
'inner_blocks' => array(
'enabled' => false,
'position' => 'above',
'template' => null,
'template_lock' => null,
'allowed_blocks' => null,
),
'category' => array(
'slug' => 'common',
),
Expand Down Expand Up @@ -221,6 +229,117 @@ public function set_preview_mode( $preview = true ) {
return $this;
}

/**
* Set the parent block(s) in which the block type can be inserted.
*
* @see https://wordpress.org/gutenberg/handbook/designers-developers/developers/block-api/block-registration/#parent-optional
*
* @param string|string[]|null $parent
* @return Block_Container
*/
public function set_parent( $parent = null ) {
if ( ! is_array( $parent ) && ! is_string( $parent ) && ! is_null( $parent ) ) {
throw new \Exception( __( "The parent must be 'array', 'string' or 'null'.", 'crb' ) );
}

$this->settings[ 'parent' ] = is_string( $parent ) ? array( $parent ) : $parent;

return $this;
}

/**
* Set whether the inner blocks are available for the block type.
*
* @param boolean $inner_blocks
* @return Block_Container
*/
public function set_inner_blocks( $inner_blocks = true ) {
$this->settings[ 'inner_blocks' ][ 'enabled' ] = $inner_blocks;

return $this;
}

/**
* Set the position of the inner blocks to be rendered
* above or below the fields.
*
* @param string $position
* @return Block_Container
*/
public function set_inner_blocks_position( $position = 'above' ) {
if ( ! in_array( $position, [ 'above', 'below' ] ) ) {
throw new \Exception( __( "The position of inner blocks must be 'above' or 'below'.", 'crb' ) );
}

$this->settings[ 'inner_blocks' ][ 'position' ] = $position;

return $this;
}

/**
* Set the default template that should be rendered in inner blocks.
*
* @see https://github.com/WordPress/gutenberg/tree/master/packages/editor/src/components/inner-blocks#template
*
* @param array[]|null $template
* @return Block_Container
*/
public function set_inner_blocks_template( $template = null ) {
if ( ! is_array( $template ) && ! is_null( $template ) ) {
throw new \Exception( __( "The template must be an 'array' or 'null'.", 'crb' ) );
}

$this->settings[ 'inner_blocks' ][ 'template' ] = $template;

return $this;
}

/**
* Set the lock mode used by template of inner blocks.
*
* @see https://github.com/WordPress/gutenberg/tree/master/packages/editor/src/components/inner-blocks#templatelock
*
* @param string|boolean|null $lock
* @return Block_Container
*/
public function set_inner_blocks_template_lock( $lock = null ) {
if ( is_string( $lock ) && ! in_array( $lock, [ 'all', 'insert' ] ) ) {
throw new \Exception( __( "The template lock must be 'all', 'insert', 'false' or 'null'.", 'crb' ) );
}

$this->settings[ 'inner_blocks' ][ 'template_lock' ] = $lock;

return $this;
}

/**
* Set the list of allowed blocks that can be inserted.
*
* @see https://github.com/WordPress/gutenberg/tree/master/packages/editor/src/components/inner-blocks#allowedblocks
*
* @param string[]|null $blocks
* @return Block_Container
*/
public function set_allowed_inner_blocks( $blocks = null ) {
if ( ! is_array( $blocks ) && ! is_null( $blocks ) ) {
throw new \Exception( __( "The allowed blocks must be an 'array' or 'null'.", 'crb' ) );
}

if ( is_array( $blocks ) ) {
$this->settings[ 'inner_blocks' ][ 'allowed_blocks' ] = array_map( function ( $block ) {
if ( $block instanceof self ) {
return $block->get_block_type_name();
}

return $block;
}, $blocks );
} else {
$this->settings[ 'inner_blocks' ][ 'allowed_blocks' ] = $blocks;
}

return $this;
}

/**
* Set the render callback of the block type.
*
Expand All @@ -239,16 +358,30 @@ public function set_render_callback( $render_callback ) {
* Render the block type.
*
* @param array $attributes
* @param string $content
* @return string
*/
public function render_block( $attributes ) {
public function render_block( $attributes, $content ) {
$fields = $attributes['data'];

// Unset the "data" property because we
// pass it as separate argument to the callback.
unset($attributes['data']);

ob_start();

call_user_func( $this->render_callback , $attributes[ 'data' ] );
call_user_func( $this->render_callback , $fields, $attributes, $content );

return ob_get_clean();
}

/**
* Returns the block type name, e.g. "carbon-fields/testimonial"
*/
private function get_block_type_name() {
return str_replace( 'carbon-fields-container-', 'carbon-fields/', str_replace( '_', '-', $this->id ) );
}

/**
* Register the block type.
*
Expand All @@ -263,7 +396,6 @@ protected function register_block() {
throw new \Exception( __( "'render_callback' must be a callable.", 'crb' ) );
}

$name = str_replace( 'carbon-fields-container-', 'carbon-fields/', str_replace( '_', '-', $this->id ) );
$style = isset( $this->settings[ 'style' ] ) ? $this->settings[ 'style' ] : null;
$editor_style = isset( $this->settings[ 'editor_style' ] ) ? $this->settings[ 'editor_style' ] : null;
$attributes = array_reduce( $this->get_fields(), function( $attributes, $field ) {
Expand All @@ -277,7 +409,7 @@ protected function register_block() {
),
) );

register_block_type( $name, array(
register_block_type( $this->get_block_type_name(), array(
'style' => $style,
'editor_style' => $editor_style,
'attributes' => $attributes,
Expand Down
114 changes: 114 additions & 0 deletions core/REST_API/Router.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ class Router {
'permission_callback' => 'allow_access',
'methods' => 'GET',
),
'block_renderer' => array(
'path' => '/block-renderer',
'callback' => 'block_renderer',
'permission_callback' => 'block_renderer_permission',
'methods' => 'POST',
'args' => 'block_renderer_args_schema',
)
);

/**
Expand Down Expand Up @@ -177,6 +184,7 @@ protected function register_route( $route ) {
'methods' => $route['methods'],
'permission_callback' => array( $this, $route['permission_callback'] ),
'callback' => array( $this, $route['callback'] ),
'args' => isset( $route['args'] ) ? call_user_func( array( $this, $route['args'] ) ) : array(),
) );
}

Expand Down Expand Up @@ -351,4 +359,110 @@ protected function set_options( $request ) {

return new \WP_REST_Response( __( 'Theme Options updated.', 'carbon-fields' ), 200 );
}

/**
* Checks if a given request has access to read blocks.
*
* @see https://github.com/WordPress/WordPress/blob/master/wp-includes/rest-api/endpoints/class-wp-rest-block-renderer-controller.php#L78-L116
*
* @param WP_REST_Request
* @return true|WP_Error
*/
public function block_renderer_permission( $request ) {
global $post;

$post_id = isset( $request['post_id'] ) ? intval( $request['post_id'] ) : 0;

if ( 0 < $post_id ) {
$post = get_post( $post_id );

if ( ! $post || ! current_user_can( 'edit_post', $post->ID ) ) {
return new \WP_Error(
'block_cannot_read',
__( 'Sorry, you are not allowed to read blocks of this post.', 'carbon-fields' ),
array(
'status' => rest_authorization_required_code(),
)
);
}
} else {
if ( ! current_user_can( 'edit_posts' ) ) {
return new \WP_Error(
'block_cannot_read',
__( 'Sorry, you are not allowed to read blocks as this user.', 'carbon-fields' ),
array(
'status' => rest_authorization_required_code(),
)
);
}
}

return true;
}

/**
* Returns the schema of the accepted arguments.
*
* @see https://github.com/WordPress/WordPress/blob/master/wp-includes/rest-api/endpoints/class-wp-rest-block-renderer-controller.php#L56-L71
*
* @return array
*/
public function block_renderer_args_schema() {
return array(
'name' => array(
'type' => 'string',
'required' => true,
'description' => __( 'The name of the block.', 'carbon-fields' ),
),
'content' => array(
'type' => 'string',
'required' => true,
'description' => __( 'The content of the block.', 'carbon-fields' ),
),
'post_id' => array(
'type' => 'integer',
'description' => __( 'ID of the post context.', 'carbon-fields' ),
),
);
}

/**
* Returns block output from block's registered render_callback.
*
* @see https://github.com/WordPress/WordPress/blob/master/wp-includes/rest-api/endpoints/class-wp-rest-block-renderer-controller.php#L118-L154
*
* @param WP_REST_Request $request
* @return WP_REST_Response|WP_Error
*/
public function block_renderer( $request ) {
global $post;

$post_id = isset( $request['post_id'] ) ? intval( $request['post_id'] ) : 0;

if ( 0 < $post_id ) {
$post = get_post( $post_id );

// Set up postdata since this will be needed if post_id was set.
setup_postdata( $post );
}

$registry = \WP_Block_Type_Registry::get_instance();
$block = $registry->get_registered( $request['name'] );

if ( null === $block ) {
return new \WP_Error(
'block_invalid',
__( 'Invalid block.' ),
array(
'status' => 404,
)
);
}

$data = array(
'rendered' => do_blocks( $request['content'] ),
);

return rest_ensure_response( $data );
}
}
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "carbon-fields",
"version": "3.0.2",
"version": "3.1.0-beta.1",
"description": "WordPress developer-friendly custom fields for post types, taxonomy terms, users, comments, widgets, options, navigation menus and more.",
"directories": {
"test": "tests"
Expand Down Expand Up @@ -61,6 +61,7 @@
},
"dependencies": {
"@babel/runtime": "^7.1.5",
"@wordpress/api-fetch": "^2.2.8",
"@wordpress/blocks": "^6.0.2",
"@wordpress/components": "^7.0.3",
"@wordpress/compose": "^3.0.0",
Expand Down
Loading

0 comments on commit cedc8b2

Please sign in to comment.