Skip to content

Commit

Permalink
Fix fallback from setter to macro
Browse files Browse the repository at this point in the history
  • Loading branch information
kylekatarnls committed Jan 24, 2024
1 parent e61a85b commit 4fab0bc
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 5 deletions.
10 changes: 10 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,16 @@ parameters:
message: '#^Parameter \$foo of anonymous function has invalid type Tests\\Factory\\FooBar\.#'
paths:
- tests/Factory/CallbackTest.php
-
message: '#^Call to an undefined method Tests\\Carbon(Immutable)?\\MacroTest::diffInYears\(\)\.#'
paths:
- tests/Carbon/MacroTest.php
- tests/CarbonImmutable/MacroTest.php
-
message: '#^Call to an undefined method SubCarbon(Immutable)?::diffInDecades\(\)\.#'
paths:
- tests/Carbon/MacroTest.php
- tests/CarbonImmutable/MacroTest.php
excludePaths:
- '*/src/Carbon/CarbonPeriod.php'
- '*/src/Carbon/Laravel/ServiceProvider.php'
Expand Down
19 changes: 15 additions & 4 deletions src/Carbon/Traits/Date.php
Original file line number Diff line number Diff line change
Expand Up @@ -2748,10 +2748,8 @@ public function __call(string $method, array $parameters): mixed
$this->localStrictModeEnabled = true;

try {
$value = isset($parameters[0])
? $this->set($method, $parameters[0])
: $this->get($method);
} catch (UnknownGetterException|UnknownSetterException) {
$value = $this->callGetOrSet($method, $parameters[0] ?? null);
} catch (UnknownGetterException|UnknownSetterException|ImmutableException) {
// continue to macro
} finally {
$this->localStrictModeEnabled = $localStrictModeEnabled;
Expand Down Expand Up @@ -2890,4 +2888,17 @@ protected function getTranslatedFormByRegExp($baseKey, $keySuffix, $context, $su

return $this->getTranslationMessage("$key.$subKey", null, $defaultValue);
}

private function callGetOrSet(string $name, mixed $value): mixed
{
if ($value !== null) {
if (\is_string($value) || \is_int($value) || \is_float($value) || $value instanceof DateTimeZone || $value instanceof Month) {
return $this->set($name, $value);
}

return null;
}

return $this->get($name);
}
}
17 changes: 17 additions & 0 deletions tests/Carbon/MacroTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use Carbon\CarbonInterface;
use CarbonTimezoneTrait;
use DateTime;
use SubCarbon;
use Tests\AbstractTestCaseWithOldNow;
use Tests\Carbon\Fixtures\FooBar;
use Tests\Carbon\Fixtures\Mixin;
Expand Down Expand Up @@ -326,4 +327,20 @@ public function testMutabilityOfMixinMethodReturnedValue()
$this->assertEquals($mutated, $copy);
$this->assertNotSame($mutated, $copy);
}

public function testSubClassMacro()
{
require_once __DIR__.'/../Fixtures/SubCarbon.php';

$subCarbon = new SubCarbon('2024-01-24 00:00');

SubCarbon::macro('diffInDecades', function (SubCarbon|string $dt = null, $abs = true) {
return (int) ($this->diffInYears($dt, $abs) / 10);
});

$this->assertSame(2, $subCarbon->diffInDecades(new SubCarbon('2049-01-24 00:00')));
$this->assertSame(2, $subCarbon->diffInDecades('2049-01-24 00:00'));

SubCarbon::resetMacros();
}
}
1 change: 0 additions & 1 deletion tests/CarbonImmutable/ComparisonTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,5 @@ public function testDifferentType()
$subCarbon = new SubCarbon('2024-01-24 00:00');
$carbon = new Carbon('2024-01-24 00:00');
$this->assertTrue($subCarbon->equalTo($carbon));
$this->assertTrue($carbon->equalTo($subCarbon));
}
}
17 changes: 17 additions & 0 deletions tests/CarbonImmutable/MacroTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use BadMethodCallException;
use Carbon\CarbonImmutable as Carbon;
use CarbonTimezoneTrait;
use SubCarbonImmutable;
use Tests\AbstractTestCaseWithOldNow;
use Tests\Carbon\Fixtures\FooBar;
use Tests\CarbonImmutable\Fixtures\Mixin;
Expand Down Expand Up @@ -163,4 +164,20 @@ public function testSerializationAfterTraitChaining()

$this->assertSame('2023-06-12 13:49 Europe/Paris', unserialize(serialize($date))->format('Y-m-d H:i e'));
}

public function testSubClassMacro()
{
require_once __DIR__.'/../Fixtures/SubCarbonImmutable.php';

$subCarbon = new SubCarbonImmutable('2024-01-24 00:00');

SubCarbonImmutable::macro('diffInDecades', function (SubCarbonImmutable|string $dt = null, $abs = true) {
return (int) ($this->diffInYears($dt, $abs) / 10);
});

$this->assertSame(2, $subCarbon->diffInDecades(new SubCarbonImmutable('2049-01-24 00:00')));
$this->assertSame(2, $subCarbon->diffInDecades('2049-01-24 00:00'));

SubCarbonImmutable::resetMacros();
}
}
18 changes: 18 additions & 0 deletions tests/Fixtures/SubCarbonImmutable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

/**
* This file is part of the Carbon package.
*
* (c) Brian Nesbitt <brian@nesbot.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

use Carbon\CarbonImmutable;

class SubCarbonImmutable extends CarbonImmutable
{
}

0 comments on commit 4fab0bc

Please sign in to comment.