Skip to content

Commit

Permalink
Split CarbonPeriod construction into multiple steps
Browse files Browse the repository at this point in the history
  • Loading branch information
kylekatarnls committed May 25, 2024
1 parent 8eab898 commit c852674
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 40 deletions.
4 changes: 4 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ parameters:
message: '#^Call to an undefined method Symfony\\Contracts\\Translation\\TranslatorInterface::getMessages\(\)\.#'
paths:
- tests/CarbonInterval/ConstructTest.php
-
message: '#^Access to protected property Carbon\\CarbonPeriod::\$dateInterval\.#'
paths:
- tests/CarbonPeriod/CreateTest.php
excludePaths:
- '*/src/Carbon/CarbonPeriod.php'
- '*/src/Carbon/Laravel/ServiceProvider.php'
Expand Down
85 changes: 45 additions & 40 deletions src/Carbon/CarbonPeriod.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@
use ReturnTypeWillChange;
use RuntimeException;
use Throwable;
use TypeError;

// @codeCoverageIgnoreStart
require PHP_VERSION < 8.2
Expand Down Expand Up @@ -435,7 +434,7 @@ protected static function intervalHasTime(DateInterval $interval): bool
* Return whether given variable is an ISO 8601 specification.
*
* Note: Check is very basic, as actual validation will be done later when parsing.
* We just want to ensure that variable is not any other type of a valid parameter.
* We just want to ensure that variable is not any other type of valid parameter.
*/
protected static function isIso8601(mixed $var): bool
{
Expand Down Expand Up @@ -690,44 +689,8 @@ public function __construct(...$arguments)
$raw = [$arguments[0]];
}

$constructed = false;

if ($raw !== null) {
try {
parent::__construct(...$raw);
$constructed = true;
} catch (TypeError) {
// $constructed = false
}
}

if (!$constructed) {
parent::__construct('R1/2000-01-01T00:00:00Z/P1D');
}

if (isset($sortedArguments['start'])) {
$this->setStartDate($sortedArguments['start']);
}

if (isset($sortedArguments['start'])) {
$this->setStartDate($sortedArguments['start']);
}

if (isset($sortedArguments['end'])) {
$this->setEndDate($sortedArguments['end']);
}

if (isset($sortedArguments['recurrences'])) {
$this->setRecurrences($sortedArguments['recurrences']);
}

if (isset($sortedArguments['interval'])) {
$this->setDateInterval($sortedArguments['interval']);
}

if (isset($sortedArguments['options'])) {
$this->setOptions($sortedArguments['options']);
}
$this->constructWith($raw);
$this->setFromAssociativeArray($sortedArguments);

if ($this->startDate === null) {
$dateClass = $this->dateClass;
Expand Down Expand Up @@ -2550,4 +2513,46 @@ private static function setDefaultParameters(array &$parameters, array $defaults
}
}
}

private function constructWith(?array $raw): void
{
if ($raw !== null) {
try {
parent::__construct(...$raw);

return;
} catch (Throwable) { // @coverCoverageIgnore
// Fallback construct
}
}

parent::__construct('R1/2000-01-01T00:00:00Z/P1D');
}

private function setFromAssociativeArray(array $parameters): void
{
if (isset($parameters['start'])) {
$this->setStartDate($parameters['start']);
}

if (isset($parameters['start'])) {
$this->setStartDate($parameters['start']);
}

if (isset($parameters['end'])) {
$this->setEndDate($parameters['end']);
}

if (isset($parameters['recurrences'])) {
$this->setRecurrences($parameters['recurrences']);
}

if (isset($parameters['interval'])) {
$this->setDateInterval($parameters['interval']);
}

if (isset($parameters['options'])) {
$this->setOptions($parameters['options']);
}
}
}
16 changes: 16 additions & 0 deletions tests/CarbonPeriod/CreateTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -898,4 +898,20 @@ public function testStartAndEndFallback()
$period->end?->format('Y-m-d'),
]);
}

public function testSlashFormat()
{
$periodClass = static::$periodClass;
$period = $periodClass::create('2024-09-01/3 days/2024-09-30');

$this->assertSame('+3', $period->interval->format('%R%d'));
$this->assertSame('3 days', $period->dateInterval->forHumans());
$this->assertSame([
'2024-09-01',
'2024-09-30',
], [
$period->start->format('Y-m-d'),
$period->end->format('Y-m-d'),
]);
}
}

0 comments on commit c852674

Please sign in to comment.