From 4c4c3987fdfeadfba47a1679f97ee4867f1b2912 Mon Sep 17 00:00:00 2001 From: Dany Maillard Date: Fri, 21 Jul 2017 17:12:27 +0200 Subject: [PATCH] Add period caster --- .../Component/VarDumper/Caster/DateCaster.php | 34 +++++++ .../VarDumper/Cloner/AbstractCloner.php | 1 + .../VarDumper/Tests/Caster/DateCasterTest.php | 93 +++++++++++++++++++ 3 files changed, 128 insertions(+) diff --git a/src/Symfony/Component/VarDumper/Caster/DateCaster.php b/src/Symfony/Component/VarDumper/Caster/DateCaster.php index 17e7f4f92906..a23a5bb25afe 100644 --- a/src/Symfony/Component/VarDumper/Caster/DateCaster.php +++ b/src/Symfony/Component/VarDumper/Caster/DateCaster.php @@ -80,6 +80,40 @@ public static function castTimeZone(\DateTimeZone $timeZone, array $a, Stub $stu return $filter & Caster::EXCLUDE_VERBOSE ? $z : $z + $a; } + public static function castPeriod(\DatePeriod $p, array $a, Stub $stub, $isNested, $filter) + { + if (defined('HHVM_VERSION_ID') || \PHP_VERSION_ID < 50605) { + return $a; + } + + $dates = array(); + if (\PHP_VERSION_ID >= 70107) { // see https://bugs.php.net/bug.php?id=74639 + foreach (clone $p as $i => $d) { + if (3 === $i) { + $now = new \DateTimeImmutable(); + $dates[] = sprintf('%s more', ($end = $p->getEndDate()) + ? ceil(($end->format('U.u') - $d->format('U.u')) / ($now->add($p->getDateInterval())->format('U.u') - $now->format('U.u'))) + : $p->recurrences - $i + ); + break; + } + $dates[] = sprintf('%s) %s', $i + 1, $d->format('Y-m-d H:i:s')); + } + } + + $period = sprintf( + 'every %s, from %s (%s) %s', + self::formatInterval($p->getDateInterval()), + $p->getStartDate()->format('Y-m-d H:i:s'), + $p->include_start_date ? 'included' : 'excluded', + ($end = $p->getEndDate()) ? 'to '.$end->format('Y-m-d H:i:s') : 'recurring '.$p->recurrences.' time/s' + ); + + $p = array(Caster::PREFIX_VIRTUAL.'period' => new ConstStub($period, implode("\n", $dates))); + + return $filter & Caster::EXCLUDE_VERBOSE ? $p : $p + $a; + } + private static function formatSeconds($s, $us) { return sprintf('%02d.%s', $s, 0 === ($len = strlen($t = rtrim($us, '0'))) ? '0' : ($len <= 3 ? str_pad($t, 3, '0') : $us)); diff --git a/src/Symfony/Component/VarDumper/Cloner/AbstractCloner.php b/src/Symfony/Component/VarDumper/Cloner/AbstractCloner.php index 2c13341f31fd..5e0a0b153138 100644 --- a/src/Symfony/Component/VarDumper/Cloner/AbstractCloner.php +++ b/src/Symfony/Component/VarDumper/Cloner/AbstractCloner.php @@ -112,6 +112,7 @@ abstract class AbstractCloner implements ClonerInterface 'DateTimeInterface' => array('Symfony\Component\VarDumper\Caster\DateCaster', 'castDateTime'), 'DateInterval' => array('Symfony\Component\VarDumper\Caster\DateCaster', 'castInterval'), 'DateTimeZone' => array('Symfony\Component\VarDumper\Caster\DateCaster', 'castTimeZone'), + 'DatePeriod' => array('Symfony\Component\VarDumper\Caster\DateCaster', 'castPeriod'), ':curl' => array('Symfony\Component\VarDumper\Caster\ResourceCaster', 'castCurl'), ':dba' => array('Symfony\Component\VarDumper\Caster\ResourceCaster', 'castDba'), diff --git a/src/Symfony/Component/VarDumper/Tests/Caster/DateCasterTest.php b/src/Symfony/Component/VarDumper/Tests/Caster/DateCasterTest.php index f1207e30d16f..dff66454911f 100644 --- a/src/Symfony/Component/VarDumper/Tests/Caster/DateCasterTest.php +++ b/src/Symfony/Component/VarDumper/Tests/Caster/DateCasterTest.php @@ -296,4 +296,97 @@ public function provideTimeZones() array('Pacific/Tahiti', 'Pacific/Tahiti (-10:00)', $xRegion), ); } + + /** + * @dataProvider providePeriods + */ + public function testDumpPeriod($start, $interval, $end, $options, $expected) + { + if (defined('HHVM_VERSION_ID') || \PHP_VERSION_ID < 50605) { + $this->markTestSkipped(); + } + + $p = new \DatePeriod(new \DateTime($start), new \DateInterval($interval), is_int($end) ? $end : new \DateTime($end), $options); + + $xDump = <<assertDumpMatchesFormat($xDump, $p); + } + + /** + * @dataProvider providePeriods + */ + public function testCastPeriod($start, $interval, $end, $options, $xPeriod, $xDates) + { + if (defined('HHVM_VERSION_ID') || \PHP_VERSION_ID < 50605) { + $this->markTestSkipped(); + } + + $p = new \DatePeriod(new \DateTime($start), new \DateInterval($interval), is_int($end) ? $end : new \DateTime($end), $options); + $stub = new Stub(); + + $cast = DateCaster::castPeriod($p, array(), $stub, false, 0); + + $xDump = << $xPeriod +] +EODUMP; + + $this->assertDumpMatchesFormat($xDump, $cast); + + $xDump = <<assertDumpMatchesFormat($xDump, $cast["\0~\0period"]); + } + + public function providePeriods() + { + $i = new \DateInterval('PT0S'); + $ms = \PHP_VERSION_ID >= 70100 && isset($i->f) ? '.0' : ''; + + $periods = array( + array('2017-01-01', 'P1D', '2017-01-03', 0, 'every + 1d, from 2017-01-01 00:00:00 (included) to 2017-01-03 00:00:00', '1) 2017-01-01%a2) 2017-01-02'), + array('2017-01-01', 'P1D', 1, 0, 'every + 1d, from 2017-01-01 00:00:00 (included) recurring 2 time/s', '1) 2017-01-01%a2) 2017-01-02'), + + array('2017-01-01', 'P1D', '2017-01-04', 0, 'every + 1d, from 2017-01-01 00:00:00 (included) to 2017-01-04 00:00:00', '1) 2017-01-01%a2) 2017-01-02%a3) 2017-01-03'), + array('2017-01-01', 'P1D', 2, 0, 'every + 1d, from 2017-01-01 00:00:00 (included) recurring 3 time/s', '1) 2017-01-01%a2) 2017-01-02%a3) 2017-01-03'), + + array('2017-01-01', 'P1D', '2017-01-05', 0, 'every + 1d, from 2017-01-01 00:00:00 (included) to 2017-01-05 00:00:00', '1) 2017-01-01%a2) 2017-01-02%a1 more'), + array('2017-01-01', 'P1D', 3, 0, 'every + 1d, from 2017-01-01 00:00:00 (included) recurring 4 time/s', '1) 2017-01-01%a2) 2017-01-02%a3) 2017-01-03%a1 more'), + + array('2017-01-01', 'P1D', '2017-01-21', 0, 'every + 1d, from 2017-01-01 00:00:00 (included) to 2017-01-21 00:00:00', '1) 2017-01-01%a17 more'), + array('2017-01-01', 'P1D', 19, 0, 'every + 1d, from 2017-01-01 00:00:00 (included) recurring 20 time/s', '1) 2017-01-01%a17 more'), + + array('2017-01-01 01:00:00', 'P1D', '2017-01-03 01:00:00', 0, 'every + 1d, from 2017-01-01 01:00:00 (included) to 2017-01-03 01:00:00', '1) 2017-01-01 01:00:00%a2) 2017-01-02 01:00:00'), + array('2017-01-01 01:00:00', 'P1D', 1, 0, 'every + 1d, from 2017-01-01 01:00:00 (included) recurring 2 time/s', '1) 2017-01-01 01:00:00%a2) 2017-01-02 01:00:00'), + + array('2017-01-01', 'P1DT1H', '2017-01-03', 0, "every + 1d 01:00:00$ms, from 2017-01-01 00:00:00 (included) to 2017-01-03 00:00:00", '1) 2017-01-01 00:00:00%a2) 2017-01-02 01:00:00'), + array('2017-01-01', 'P1DT1H', 1, 0, "every + 1d 01:00:00$ms, from 2017-01-01 00:00:00 (included) recurring 2 time/s", '1) 2017-01-01 00:00:00%a2) 2017-01-02 01:00:00'), + + array('2017-01-01', 'P1D', '2017-01-04', \DatePeriod::EXCLUDE_START_DATE, 'every + 1d, from 2017-01-01 00:00:00 (excluded) to 2017-01-04 00:00:00', '1) 2017-01-02%a2) 2017-01-03'), + array('2017-01-01', 'P1D', 2, \DatePeriod::EXCLUDE_START_DATE, 'every + 1d, from 2017-01-01 00:00:00 (excluded) recurring 2 time/s', '1) 2017-01-02%a2) 2017-01-03'), + ); + + if (\PHP_VERSION_ID < 70107) { + array_walk($periods, function (&$i) { $i[5] = ''; }); + } + + return $periods; + } }