Skip to content

Commit

Permalink
Add a NodeInterface::clone() method.
Browse files Browse the repository at this point in the history
  • Loading branch information
drupol committed Jun 14, 2019
1 parent f073959 commit 6fd1ed1
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 3 deletions.
20 changes: 20 additions & 0 deletions spec/drupol/phptree/Node/ValueNodeSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,30 @@

namespace spec\drupol\phptree\Node;

use drupol\phptree\Exporter\Text;
use drupol\phptree\Node\ValueNode;

class ValueNodeSpec extends NodeObjectBehavior
{
public function it_can_be_cloned()
{
$this->beConstructedWith(2);

$node1 = new ValueNode(\mt_rand());
$node2 = new ValueNode(\mt_rand());
$node3 = new ValueNode(\mt_rand());
$node4 = new ValueNode(\mt_rand());

$this
->add($node1->add($node2), $node3->add($node4));

$exporter = new Text();

$export = $exporter->export($this->getWrappedObject()->clone());

$this->shouldHaveSameTextExport($export);
}

public function it_can_be_manipulated_like_an_array()
{
$this
Expand Down
27 changes: 26 additions & 1 deletion src/Node/Node.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,29 @@ public function children(): \Traversable
yield from $this->storage()->getChildren();
}

/**
* {@inheritdoc}
*/
public function clone(): NodeInterface
{
// @todo: Replace with something better.
return \unserialize(\serialize($this));
// @todo: Unable to get this code working yet.
/*
$root = $this;
$root = clone $root;
$children = [];
foreach ($root->children() as $key => $child) {
$children[] = $child->clone();
}
return $root->withChildren(...$children);
*/
}

/**
* {@inheritdoc}
*/
Expand Down Expand Up @@ -273,11 +296,13 @@ public function setParent(?NodeInterface $node): NodeInterface
/**
* {@inheritdoc}
*/
public function withChildren(NodeInterface ...$nodes): NodeInterface
public function withChildren(?NodeInterface ...$nodes): NodeInterface
{
$clone = clone $this;
$clone->storage()->getChildren()->exchangeArray([]);

$nodes = \array_filter($nodes);

return [] === $nodes ?
$clone :
$clone->add(...$nodes);
Expand Down
12 changes: 10 additions & 2 deletions src/Node/NodeInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ public function all(): \Traversable;
*/
public function children(): \Traversable;

/**
* Clone the tree and all of its children.
*
* @return \drupol\phptree\Node\NodeInterface
* The tree.
*/
public function clone(): NodeInterface;

/**
* The amount of children a node has.
*
Expand Down Expand Up @@ -147,11 +155,11 @@ public function setParent(?NodeInterface $node): NodeInterface;
/**
* Get a clone of the object with or without children.
*
* @param \drupol\phptree\Node\NodeInterface ...$nodes
* @param null|\drupol\phptree\Node\NodeInterface ...$nodes
* The children that the clone will have.
*
* @return \drupol\phptree\Node\NodeInterface
* The new object
*/
public function withChildren(NodeInterface ...$nodes): NodeInterface;
public function withChildren(?NodeInterface ...$nodes): NodeInterface;
}

0 comments on commit 6fd1ed1

Please sign in to comment.