Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Block API: WP_Block implements JsonSerializable, Serializable, IteratorAggregate, Countable #21798

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 88 additions & 7 deletions lib/class-wp-block.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
/**
* Class representing a parsed instance of a block.
*/
class WP_Block implements ArrayAccess {
class WP_Block implements ArrayAccess, JsonSerializable, Serializable, IteratorAggregate, Countable {

/**
* Name of block.
Expand Down Expand Up @@ -177,6 +177,10 @@ public function render() {
return $block_content;
}

/*
* ArrayAccess interface methods.
*/

/**
* Returns true if an attribute exists by the specified attribute name, or
* false otherwise.
Expand All @@ -201,9 +205,11 @@ public function offsetExists( $attribute_name ) {
* @return mixed|null Attribute value if exists, or null.
*/
public function offsetGet( $attribute_name ) {
// This may cause an "Undefined index" notice if the attribute name does
// not exist. This is expected, since the purpose of this implementation
// is to align exactly to the expectations of operating on an array.
/*
* This may cause an "Undefined index" notice if the attribute name does
* not exist. This is expected, since the purpose of this implementation
* is to align exactly to the expectations of operating on an array.
*/
return $this->attributes[ $attribute_name ];
}

Expand All @@ -217,9 +223,11 @@ public function offsetGet( $attribute_name ) {
*/
public function offsetSet( $attribute_name, $value ) {
if ( is_null( $attribute_name ) ) {
// This is not technically a valid use-case for attributes. Since
// this implementation is expected to align to expectations of
// operating on an array, it is still supported.
/*
* This is not technically a valid use-case for attributes. Since
* this implementation is expected to align to expectations of
* operating on an array, it is still supported.
*/
$this->attributes[] = $value;
} else {
$this->attributes[ $attribute_name ] = $value;
Expand All @@ -237,4 +245,77 @@ public function offsetUnset( $attribute_name ) {
unset( $this->attributes[ $attribute_name ] );
}

/*
* Serializable interface methods.
*/

/**
* Returns the string representation of the block attributes.
*
* @link https://www.php.net/manual/en/serializable.serialize.php
*
* @return string String representation of the block attributes.
*/
public function serialize() {
return serialize( $this->attributes );
}

/**
* Constructs the object from a serialized representation of block
* attributes.
*
* @link https://www.php.net/manual/en/serializable.unserialize.php
*
* @param string The string representation of the block attributes.
*/
public function unserialize( $serialized ) {
$this->attributes = unserialize( $serialized );
}

/*
* JsonSerializable interface methods.
*/

/**
* Serializes the object to an array of attributes that can be serialized
* natively by json_encode().
*
* @link https://www.php.net/manual/en/jsonserializable.jsonserialize.php
*
* @return array Array data which can be serialized by json_encode().
*/
public function jsonSerialize() {
return $this->attributes;
}

/*
* IteratorAggregate interface methods.
*/

/**
* Returns an iterator of the block attributes.
*
* @link https://www.php.net/manual/en/iteratoraggregate.getiterator.php
*
* @return Traversable Attributes iterator.
*/
public function getIterator() {
return new ArrayIterator( $this->attributes );
}

/*
* Countable interface methods.
*/

/**
* Returns the count of the block attributes.
*
* @link https://www.php.net/manual/en/countable.count.php
*
* @return int Count of the block attributes.
*/
public function count() {
return count( $this->attributes );
}

}
91 changes: 91 additions & 0 deletions phpunit/class-wp-block-test.php
Original file line number Diff line number Diff line change
Expand Up @@ -367,4 +367,95 @@ function test_array_access_attributes() {
$this->assertEquals( 'invalid, but still supported', $block[0] );
}

function test_block_serializable_as_attributes_array() {
$this->registry->register(
'core/example',
array(
'attributes' => array(
'value' => array(
'type' => 'string',
'default' => 'ok',
),
),
)
);

$parsed_block = array( 'blockName' => 'core/example' );
$context = array();
$block = new WP_Block( $parsed_block, $context, $this->registry );

$result = serialize( $block );

$this->assertEquals( 'C:8:"WP_Block":27:{a:1:{s:5:"value";s:2:"ok";}}', $result );
}

function test_block_json_serializable_as_attributes_array() {
$this->registry->register(
'core/example',
array(
'attributes' => array(
'value' => array(
'type' => 'string',
'default' => 'ok',
),
),
)
);

$parsed_block = array( 'blockName' => 'core/example' );
$context = array();
$block = new WP_Block( $parsed_block, $context, $this->registry );

$result = json_encode( $block );

$this->assertEquals( '{"value":"ok"}', $result );
}

function test_iterable_as_attributes_array() {
$this->registry->register(
'core/example',
array(
'attributes' => array(
'value' => array(
'type' => 'string',
'default' => 'ok',
),
),
)
);

$parsed_block = array( 'blockName' => 'core/example' );
$context = array();
$block = new WP_Block( $parsed_block, $context, $this->registry );

$result_attributes = array();
foreach ( $block as $key => $value ) {
$result_attributes[ $key ] = $value;
}

$this->assertEquals( array( 'value' => 'ok' ), $result_attributes );
}

function test_countable_as_attributes_array() {
$this->registry->register(
'core/example',
array(
'attributes' => array(
'value' => array(
'type' => 'string',
'default' => 'ok',
),
),
)
);

$parsed_block = array( 'blockName' => 'core/example' );
$context = array();
$block = new WP_Block( $parsed_block, $context, $this->registry );

$result = count( $block );

$this->assertEquals( 1, $result );
}

}