Add BlockInterface::is_detached()

This commit is contained in:
Matt Sherman 2023-09-11 19:58:32 -04:00
parent 94c6807a96
commit c37cd715d7
6 changed files with 74 additions and 41 deletions

View File

@ -62,22 +62,20 @@ interface BlockInterface {
/**
* Get the parent container that the block belongs to.
*
* @throws \RuntimeException If the block does not have a parent.
*/
public function &get_parent(): ?ContainerInterface;
public function &get_parent(): ContainerInterface;
/**
* Get the root template that the block belongs to.
*
* @throws \RuntimeException If the block does not have a root template.
*/
public function &get_root_template(): BlockTemplateInterface;
/**
* Detach the block from its parent and root template.
* Check if the block is detached from its parent or root template.
*
* @return bool True if the block is detached from its parent or root template.
*/
public function detach();
public function is_detached(): bool;
/**
* Get the block configuration as a formatted template.

View File

@ -26,13 +26,6 @@ interface BlockTemplateInterface extends ContainerInterface {
*/
public function get_area(): string;
/**
* Get a block by ID.
*
* @param string $block_id The block ID.
*/
public function get_block( string $block_id ): ?BlockInterface;
/**
* Generate a block ID based on a base.
*

View File

@ -16,6 +16,13 @@ interface ContainerInterface {
*/
public function get_formatted_template(): array;
/**
* Get a block by ID.
*
* @param string $block_id The block ID.
*/
public function get_block( string $block_id ): ?BlockInterface;
/**
* Removes a block from the container.
*

View File

@ -161,38 +161,29 @@ class AbstractBlock implements BlockInterface {
/**
* Get the template that this block belongs to.
*
* @throws \RuntimeException If the block does not have a root template.
*/
public function &get_root_template(): BlockTemplateInterface {
if ( is_null( $this->root_template ) ) {
throw new \RuntimeException( 'The block does not have a root template.' );
}
return $this->root_template;
}
/**
* Get the parent block container.
*
* @throws \RuntimeException If the block does not have a parent.
*/
public function &get_parent(): ContainerInterface {
if ( is_null( $this->parent ) ) {
throw new \RuntimeException( 'The block does not have a parent.' );
}
return $this->parent;
}
/**
* Detach the block from its parent block container and the template it belongs to.
* Check if the block is detached from its parent block container or the template it belongs to.
*
* @return bool True if the block is detached from its parent block container or the template it belongs to.
*/
public function detach() {
$this->parent = null;
$this->root_template = null;
}
public function is_detached(): bool {
$is_in_parent = $this->parent->get_block( $this->id ) === $this;
$is_in_root_template = $this->get_root_template()->get_block( $this->id ) === $this;
return ! $is_in_parent || ! $is_in_root_template;
}
/**
* Get the block configuration as a formatted template.
*

View File

@ -77,6 +77,31 @@ trait BlockContainerTrait {
return $this->is_block_descendant( $parent );
}
/**
* Get a block by ID.
*
* @param string $block_id The block ID.
*/
public function get_block( string $block_id ): ?BlockInterface {
foreach ( $this->inner_blocks as $block ) {
if ( $block->get_id() === $block_id ) {
return $block;
}
}
foreach ( $this->inner_blocks as $block ) {
if ( $block instanceof ContainerInterface ) {
$block = $block->get_block( $block_id );
if ( $block ) {
return $block;
}
}
}
return null;
}
/**
* Remove a block from the block container.
*
@ -108,10 +133,6 @@ trait BlockContainerTrait {
$parent = $block->get_parent();
$parent->remove_inner_block( $block );
// Detach block from parent and root template.
$block->detach();
}
/**

View File

@ -133,9 +133,15 @@ class BlockTest extends WC_Unit_Test_Case {
'Failed asserting that the child block was removed from the root template.'
);
$this->expectException( \RuntimeException::class );
$this->assertNull(
$block->get_block( 'test-block-id-2' ),
'Failed asserting that the child block was removed from the parent.'
);
$child_block->get_parent();
$this->assertTrue(
$child_block->is_detached(),
'Failed asserting that the child block is detached from its parent and root template.'
);
}
/**
@ -166,9 +172,15 @@ class BlockTest extends WC_Unit_Test_Case {
'Failed asserting that the nested descendent block was removed from the root template.'
);
$this->expectException( \RuntimeException::class );
$this->assertNull(
$block->get_block( 'test-block-id-2' ),
'Failed asserting that the nested descendent block was removed from the parent.'
);
$child_block->get_parent();
$this->assertTrue(
$child_block->is_detached(),
'Failed asserting that the nested descendent block is detached from its parent and root template.'
);
}
/**
@ -204,9 +216,20 @@ class BlockTest extends WC_Unit_Test_Case {
'Failed asserting that the nested descendent block was removed from the root template.'
);
$this->expectException( \RuntimeException::class );
$this->assertNull(
$block->get_block( 'test-block-id-2' ),
'Failed asserting that the child block was removed from the parent.'
);
$child_block->get_parent();
$this->assertTrue(
$block->is_detached(),
'Failed asserting that the block is detached from its parent and root template.'
);
$this->assertTrue(
$child_block->is_detached(),
'Failed asserting that the child block is detached from its parent and root template.'
);
}
/**