Skip to content

Commit d3df4c3

Browse files
committed
Make DeepCopy API final and immutable
Closes myclabs#68
1 parent 06ea10c commit d3df4c3

File tree

3 files changed

+50
-31
lines changed

3 files changed

+50
-31
lines changed

src/DeepCopy/DeepCopy.php

+27-25
Original file line numberDiff line numberDiff line change
@@ -44,31 +44,38 @@ final class DeepCopy
4444
private $useCloneMethod;
4545

4646
/**
47-
* @param bool $useCloneMethod If set to true, when an object implements the __clone() function, it will be used
48-
* instead of the regular deep cloning.
47+
* @param bool $useCloneMethod If set to true, when an object implements the __clone() function, it will
48+
* be used instead of the regular deep cloning.
49+
* @param bool $skipUncloneable If enabled, will not throw an exception when coming across an uncloneable
50+
* property.
51+
* @param Array<Filter, Matcher> List of filter-matcher pairs
52+
* @param Array<TypeFilter, TypeMatcher> List of type filter-matcher pairs
4953
*/
50-
public function __construct(bool $useCloneMethod = false)
51-
{
54+
public function __construct(
55+
bool $useCloneMethod = false,
56+
bool $skipUncloneable = true,
57+
array $filters = [],
58+
array $typeFilters = []
59+
) {
5260
$this->useCloneMethod = $useCloneMethod;
5361

54-
$this->addTypeFilter(
62+
$filters[] = [
5563
new DateIntervalFilter(),
5664
new TypeMatcher(DateInterval::class)
57-
);
58-
$this->addTypeFilter(
65+
];
66+
67+
foreach ($filters as [$filter, $matcher]) {
68+
$this->addFilter($filter, $matcher);
69+
}
70+
71+
$typeFilters[] = [
5972
new SplDoublyLinkedListFilter($this),
6073
new TypeMatcher(SplDoublyLinkedList::class)
61-
);
62-
}
74+
];
6375

64-
/**
65-
* If enabled, will not throw an exception when coming across an uncloneable property.
66-
*/
67-
public function skipUncloneable(bool $skipUncloneable = true): self
68-
{
69-
$this->skipUncloneable = $skipUncloneable;
70-
71-
return $this;
76+
foreach ($typeFilters as [$filter, $matcher]) {
77+
$this->addTypeFilter($filter, $matcher);
78+
}
7279
}
7380

7481
/**
@@ -85,12 +92,12 @@ public function copy($value)
8592
return $this->recursiveCopy($value);
8693
}
8794

88-
public function addFilter(Filter $filter, Matcher $matcher): void
95+
private function addFilter(Filter $filter, Matcher $matcher): void
8996
{
9097
$this->filters[] = [$matcher, $filter];
9198
}
9299

93-
public function addTypeFilter(TypeFilter $filter, TypeMatcher $matcher): void
100+
private function addTypeFilter(TypeFilter $filter, TypeMatcher $matcher): void
94101
{
95102
$this->typeFilters[] = [$matcher, $filter];
96103
}
@@ -146,12 +153,7 @@ private function copyObject(object $object): object
146153
return $object;
147154
}
148155

149-
throw new CloneException(
150-
sprintf(
151-
'The class "%s" is not cloneable.',
152-
$reflectedObject->getName()
153-
)
154-
);
156+
throw CloneException::unclonableClass($reflectedObject->getName());
155157
}
156158

157159
$newObject = clone $object;

src/DeepCopy/Exception/CloneException.php

+9
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,13 @@
66

77
class CloneException extends UnexpectedValueException
88
{
9+
final public static function unclonableClass(string $class): self
10+
{
11+
return new self(
12+
sprintf(
13+
'The class "%s" is not cloneable.',
14+
$class
15+
)
16+
);
17+
}
918
}

src/DeepCopy/deep_copy.php

+14-6
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,19 @@
66
* Deep copies the given value.
77
*
88
* @param mixed $value
9-
* @param bool $useCloneMethod
10-
*
11-
* @return mixed
9+
* @param bool $useCloneMethod If set to true, when an object implements the __clone() function, it will
10+
* be used instead of the regular deep cloning.
11+
* @param bool $skipUncloneable If enabled, will not throw an exception when coming across an uncloneable
12+
* property.
13+
* @param Array<Filter, Matcher> List of filter-matcher pairs
14+
* @param Array<TypeFilter, TypeMatcher> List of type filter-matcher pairs
1215
*/
13-
function deep_copy($value, $useCloneMethod = false)
14-
{
15-
return (new DeepCopy($useCloneMethod))->copy($value);
16+
public function deep_copy(
17+
$value,
18+
bool $useCloneMethod = false,
19+
bool $skipUncloneable = true,
20+
array $filters = [],
21+
array $typeFilters = []
22+
) {
23+
return (new DeepCopy($useCloneMethod, $skipUncloneable, $filters, $typeFilters))->copy($value);
1624
}

0 commit comments

Comments
 (0)