Implement block removal, including nested blocks
This commit is contained in:
parent
ec9f7d186e
commit
2726787ce6
|
@ -3,6 +3,7 @@
|
||||||
namespace Automattic\WooCommerce\Internal\Admin\BlockTemplates;
|
namespace Automattic\WooCommerce\Internal\Admin\BlockTemplates;
|
||||||
|
|
||||||
use Automattic\WooCommerce\Admin\BlockTemplates\BlockInterface;
|
use Automattic\WooCommerce\Admin\BlockTemplates\BlockInterface;
|
||||||
|
use Automattic\WooCommerce\Admin\BlockTemplates\ContainerInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trait for block containers.
|
* Trait for block containers.
|
||||||
|
@ -44,6 +45,91 @@ trait BlockContainerTrait {
|
||||||
|
|
||||||
// phpcs:enable Squiz.Commenting.FunctionCommentThrowTag.WrongNumber
|
// phpcs:enable Squiz.Commenting.FunctionCommentThrowTag.WrongNumber
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a block is a descendant of the block container.
|
||||||
|
*
|
||||||
|
* @param BlockInterface $block The block.
|
||||||
|
*/
|
||||||
|
private function is_block_descendant( BlockInterface $block ): bool {
|
||||||
|
$parent = $block->get_parent();
|
||||||
|
|
||||||
|
if ( $parent === $this ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! $parent instanceof BlockInterface ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->is_block_descendant( $parent );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a block from the block container.
|
||||||
|
*
|
||||||
|
* @param string $block_id The block ID.
|
||||||
|
*
|
||||||
|
* @throws \UnexpectedValueException If the block container is not an ancestor of the block.
|
||||||
|
*/
|
||||||
|
public function remove_block( string $block_id ) {
|
||||||
|
$root_template = $this->get_root_template();
|
||||||
|
|
||||||
|
$block = $root_template->get_block( $block_id );
|
||||||
|
|
||||||
|
if ( ! $block ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! $this->is_block_descendant( $block ) ) {
|
||||||
|
throw new \UnexpectedValueException( 'The block container is not an ancestor of the block.' );
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the block is a container, remove all of its blocks.
|
||||||
|
if ( $block instanceof ContainerInterface ) {
|
||||||
|
$block->remove_blocks();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove block from root template's cache.
|
||||||
|
$root_template = $this->get_root_template();
|
||||||
|
$root_template->uncache_block( $block->get_id() );
|
||||||
|
|
||||||
|
$parent = $block->get_parent();
|
||||||
|
$parent->remove_inner_block( $block );
|
||||||
|
|
||||||
|
// Detach block from parent and root template.
|
||||||
|
$block->detach();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove all blocks from the block container.
|
||||||
|
*/
|
||||||
|
public function remove_blocks() {
|
||||||
|
array_map(
|
||||||
|
function ( BlockInterface $block ) {
|
||||||
|
$this->remove_block( $block->get_id() );
|
||||||
|
},
|
||||||
|
$this->inner_blocks
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a block from the block container's inner blocks. This is an internal method and should not be called directly
|
||||||
|
* except for from the BlockContainerTrait's remove_block() method.
|
||||||
|
*
|
||||||
|
* @param BlockInterface $block The block.
|
||||||
|
*/
|
||||||
|
public function remove_inner_block( BlockInterface $block ) {
|
||||||
|
$this->inner_blocks = array_filter(
|
||||||
|
$this->inner_blocks,
|
||||||
|
function ( BlockInterface $inner_block ) use ( $block ) {
|
||||||
|
return $inner_block !== $block;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the inner blocks sorted by order.
|
* Get the inner blocks sorted by order.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue