Skip to content

Commit

Permalink
Make DeepCopy API final and immutable
Browse files Browse the repository at this point in the history
Closes myclabs#68
  • Loading branch information
theofidry committed Jun 11, 2018
1 parent 06ea10c commit d3df4c3
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 31 deletions.
52 changes: 27 additions & 25 deletions src/DeepCopy/DeepCopy.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,31 +44,38 @@ final class DeepCopy
private $useCloneMethod;

/**
* @param bool $useCloneMethod If set to true, when an object implements the __clone() function, it will be used
* instead of the regular deep cloning.
* @param bool $useCloneMethod If set to true, when an object implements the __clone() function, it will
* be used instead of the regular deep cloning.
* @param bool $skipUncloneable If enabled, will not throw an exception when coming across an uncloneable
* property.
* @param Array<Filter, Matcher> List of filter-matcher pairs
* @param Array<TypeFilter, TypeMatcher> List of type filter-matcher pairs
*/
public function __construct(bool $useCloneMethod = false)
{
public function __construct(
bool $useCloneMethod = false,
bool $skipUncloneable = true,
array $filters = [],
array $typeFilters = []
) {
$this->useCloneMethod = $useCloneMethod;

$this->addTypeFilter(
$filters[] = [
new DateIntervalFilter(),
new TypeMatcher(DateInterval::class)
);
$this->addTypeFilter(
];

foreach ($filters as [$filter, $matcher]) {
$this->addFilter($filter, $matcher);
}

$typeFilters[] = [
new SplDoublyLinkedListFilter($this),
new TypeMatcher(SplDoublyLinkedList::class)
);
}
];

/**
* If enabled, will not throw an exception when coming across an uncloneable property.
*/
public function skipUncloneable(bool $skipUncloneable = true): self
{
$this->skipUncloneable = $skipUncloneable;

return $this;
foreach ($typeFilters as [$filter, $matcher]) {
$this->addTypeFilter($filter, $matcher);
}
}

/**
Expand All @@ -85,12 +92,12 @@ public function copy($value)
return $this->recursiveCopy($value);
}

public function addFilter(Filter $filter, Matcher $matcher): void
private function addFilter(Filter $filter, Matcher $matcher): void
{
$this->filters[] = [$matcher, $filter];
}

public function addTypeFilter(TypeFilter $filter, TypeMatcher $matcher): void
private function addTypeFilter(TypeFilter $filter, TypeMatcher $matcher): void
{
$this->typeFilters[] = [$matcher, $filter];
}
Expand Down Expand Up @@ -146,12 +153,7 @@ private function copyObject(object $object): object
return $object;
}

throw new CloneException(
sprintf(
'The class "%s" is not cloneable.',
$reflectedObject->getName()
)
);
throw CloneException::unclonableClass($reflectedObject->getName());
}

$newObject = clone $object;
Expand Down
9 changes: 9 additions & 0 deletions src/DeepCopy/Exception/CloneException.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,13 @@

class CloneException extends UnexpectedValueException
{
final public static function unclonableClass(string $class): self
{
return new self(
sprintf(
'The class "%s" is not cloneable.',
$class
)
);
}
}
20 changes: 14 additions & 6 deletions src/DeepCopy/deep_copy.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,19 @@
* Deep copies the given value.
*
* @param mixed $value
* @param bool $useCloneMethod
*
* @return mixed
* @param bool $useCloneMethod If set to true, when an object implements the __clone() function, it will
* be used instead of the regular deep cloning.
* @param bool $skipUncloneable If enabled, will not throw an exception when coming across an uncloneable
* property.
* @param Array<Filter, Matcher> List of filter-matcher pairs
* @param Array<TypeFilter, TypeMatcher> List of type filter-matcher pairs
*/
function deep_copy($value, $useCloneMethod = false)
{
return (new DeepCopy($useCloneMethod))->copy($value);
public function deep_copy(
$value,
bool $useCloneMethod = false,
bool $skipUncloneable = true,
array $filters = [],
array $typeFilters = []
) {
return (new DeepCopy($useCloneMethod, $skipUncloneable, $filters, $typeFilters))->copy($value);
}

0 comments on commit d3df4c3

Please sign in to comment.