From 47aebd6a159e62635fa08ee00476792a7dc1a826 Mon Sep 17 00:00:00 2001 From: michalananapps <132371766+michalananapps@users.noreply.github.com> Date: Wed, 6 Nov 2024 14:34:57 +0100 Subject: [PATCH 1/2] bug: #196 Introduce a custom DatePeriodFilter that safely copies DatePeriod objects without modifying their readonly properties. --- src/DeepCopy/DeepCopy.php | 3 + .../TypeFilter/Date/DatePeriodFilter.php | 36 ++++++++++ tests/DeepCopyTest/DeepCopyTest.php | 3 + .../TypeFilter/Date/DatePeriodFilterTest.php | 67 +++++++++++++++++++ 4 files changed, 109 insertions(+) create mode 100644 src/DeepCopy/TypeFilter/Date/DatePeriodFilter.php create mode 100644 tests/DeepCopyTest/TypeFilter/Date/DatePeriodFilterTest.php diff --git a/src/DeepCopy/DeepCopy.php b/src/DeepCopy/DeepCopy.php index 084858e..f739d92 100644 --- a/src/DeepCopy/DeepCopy.php +++ b/src/DeepCopy/DeepCopy.php @@ -4,6 +4,7 @@ use ArrayObject; use DateInterval; +use DatePeriod; use DateTimeInterface; use DateTimeZone; use DeepCopy\Exception\CloneException; @@ -12,6 +13,7 @@ use DeepCopy\Matcher\Matcher; use DeepCopy\Reflection\ReflectionHelper; use DeepCopy\TypeFilter\Date\DateIntervalFilter; +use DeepCopy\TypeFilter\Date\DatePeriodFilter; use DeepCopy\TypeFilter\Spl\ArrayObjectFilter; use DeepCopy\TypeFilter\Spl\SplDoublyLinkedListFilter; use DeepCopy\TypeFilter\TypeFilter; @@ -64,6 +66,7 @@ public function __construct($useCloneMethod = false) $this->addTypeFilter(new ArrayObjectFilter($this), new TypeMatcher(ArrayObject::class)); $this->addTypeFilter(new DateIntervalFilter(), new TypeMatcher(DateInterval::class)); + $this->addTypeFilter(new DatePeriodFilter(), new TypeMatcher(DatePeriod::class)); $this->addTypeFilter(new SplDoublyLinkedListFilter($this), new TypeMatcher(SplDoublyLinkedList::class)); } diff --git a/src/DeepCopy/TypeFilter/Date/DatePeriodFilter.php b/src/DeepCopy/TypeFilter/Date/DatePeriodFilter.php new file mode 100644 index 0000000..82532b3 --- /dev/null +++ b/src/DeepCopy/TypeFilter/Date/DatePeriodFilter.php @@ -0,0 +1,36 @@ += 80200 && $element->include_end_date) { + $options |= DatePeriod::INCLUDE_END_DATE; + } + if (!$element->include_start_date) { + $options |= DatePeriod::EXCLUDE_START_DATE; + } + + if ($element->getEndDate()) { + return new DatePeriod($element->getStartDate(), $element->getDateInterval(), $element->getEndDate(), $options); + } + + return new DatePeriod($element->getStartDate(), $element->getDateInterval(), $element->getRecurrences(), $options); + } +} diff --git a/tests/DeepCopyTest/DeepCopyTest.php b/tests/DeepCopyTest/DeepCopyTest.php index 8890391..2b31536 100644 --- a/tests/DeepCopyTest/DeepCopyTest.php +++ b/tests/DeepCopyTest/DeepCopyTest.php @@ -4,6 +4,7 @@ use ArrayObject; use DateInterval; +use DatePeriod; use DateTime; use DateTimeImmutable; use DateTimeZone; @@ -158,6 +159,7 @@ public function test_it_can_copy_an_object_with_a_date_object_property() $object->d2 = new DateTimeImmutable(); $object->dtz = new DateTimeZone('UTC'); $object->di = new DateInterval('P2D'); + $object->dp = new DatePeriod(new DateTime(), new DateInterval('P2D'), 3); $copy = deep_copy($object); @@ -165,6 +167,7 @@ public function test_it_can_copy_an_object_with_a_date_object_property() $this->assertEqualButNotSame($object->d2, $copy->d2); $this->assertEqualButNotSame($object->dtz, $copy->dtz); $this->assertEqualButNotSame($object->di, $copy->di); + $this->assertEqualButNotSame($object->dp, $copy->dp); } /** diff --git a/tests/DeepCopyTest/TypeFilter/Date/DatePeriodFilterTest.php b/tests/DeepCopyTest/TypeFilter/Date/DatePeriodFilterTest.php new file mode 100644 index 0000000..e816aa1 --- /dev/null +++ b/tests/DeepCopyTest/TypeFilter/Date/DatePeriodFilterTest.php @@ -0,0 +1,67 @@ +apply($object); + + $this->assertEquals($object, $copy); + $this->assertNotSame($object, $copy); + } + + public function test_it_deep_copies_a_DatePeriod_with_exclude_start_date() + { + $object = new DatePeriod(new DateTime(), new DateInterval('P2D'), 3, DatePeriod::EXCLUDE_START_DATE); + + $filter = new DatePeriodFilter(); + + $copy = $filter->apply($object); + + $this->assertEquals($object, $copy); + $this->assertNotSame($object, $copy); + } + + /** + * @requires PHP 8.2 + */ + public function test_it_deep_copies_a_DatePeriod_with_include_end_date() + { + $object = new DatePeriod(new DateTime(), new DateInterval('P2D'), 3, DatePeriod::INCLUDE_END_DATE); + + $filter = new DatePeriodFilter(); + + $copy = $filter->apply($object); + + $this->assertEquals($object, $copy); + $this->assertNotSame($object, $copy); + } + + public function test_it_deep_copies_a_DatePeriod_with_end_date() + { + $object = new DatePeriod(new DateTime(), new DateInterval('P2D'), new DateTime('+2 days')); + + $filter = new DatePeriodFilter(); + + $copy = $filter->apply($object); + + $this->assertEquals($object, $copy); + $this->assertNotSame($object, $copy); + } +} From bed190bf6727048f666e7e60151b2572096778ab Mon Sep 17 00:00:00 2001 From: michalananapps <132371766+michalananapps@users.noreply.github.com> Date: Thu, 7 Nov 2024 11:48:22 +0100 Subject: [PATCH 2/2] bug: #196 support php7.1 --- src/DeepCopy/TypeFilter/Date/DatePeriodFilter.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/DeepCopy/TypeFilter/Date/DatePeriodFilter.php b/src/DeepCopy/TypeFilter/Date/DatePeriodFilter.php index 82532b3..6bd2f7e 100644 --- a/src/DeepCopy/TypeFilter/Date/DatePeriodFilter.php +++ b/src/DeepCopy/TypeFilter/Date/DatePeriodFilter.php @@ -31,6 +31,12 @@ public function apply($element) return new DatePeriod($element->getStartDate(), $element->getDateInterval(), $element->getEndDate(), $options); } - return new DatePeriod($element->getStartDate(), $element->getDateInterval(), $element->getRecurrences(), $options); + if (PHP_VERSION_ID >= 70217) { + $recurrences = $element->getRecurrences(); + } else { + $recurrences = $element->recurrences - $element->include_start_date; + } + + return new DatePeriod($element->getStartDate(), $element->getDateInterval(), $recurrences, $options); } }