Skip to content

Commit 44cde57

Browse files
authored
Refactor Carbon static calls to Date Facade (#402)
1 parent dedd89e commit 44cde57

File tree

10 files changed

+309
-1
lines changed

10 files changed

+309
-1
lines changed

config/sets/laravel-code-quality.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
use RectorLaravel\Rector\MethodCall\ReverseConditionableMethodCallRector;
2626
use RectorLaravel\Rector\MethodCall\ValidationRuleArrayStringValueToArrayRector;
2727
use RectorLaravel\Rector\PropertyFetch\OptionalToNullsafeOperatorRector;
28+
use RectorLaravel\Rector\StaticCall\CarbonToDateFacadeRector;
2829
use RectorLaravel\Rector\StaticCall\DispatchToHelperFunctionsRector;
2930

3031
return static function (RectorConfig $rectorConfig): void {
@@ -49,6 +50,7 @@
4950
$rectorConfig->rule(RedirectRouteToToRouteHelperRector::class);
5051
$rectorConfig->rule(AnonymousMigrationsRector::class);
5152
$rectorConfig->rule(SleepFuncToSleepStaticCallRector::class);
53+
$rectorConfig->rule(CarbonToDateFacadeRector::class);
5254
$rectorConfig->rule(DispatchToHelperFunctionsRector::class);
5355
$rectorConfig->rule(NotFilledBlankFuncCallToBlankFilledFuncCallRector::class);
5456
$rectorConfig->rule(EloquentOrderByToLatestOrOldestRector::class);

docs/rector_rules_overview.md

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# 86 Rules Overview
1+
# 87 Rules Overview
22

33
## AbortIfRector
44

@@ -479,6 +479,36 @@ Use the `$this->travelTo()` method in Laravel's `TestCase` class instead of the
479479

480480
<br>
481481

482+
## CarbonToDateFacadeRector
483+
484+
Refactor Carbon static method calls to use the Date facade instead.
485+
486+
- class: [`RectorLaravel\Rector\StaticCall\CarbonToDateFacadeRector`](../src/Rector/StaticCall/CarbonToDateFacadeRector.php)
487+
488+
```diff
489+
-use Carbon\Carbon;
490+
+use Illuminate\Support\Facades\Date;
491+
492+
-Carbon::now();
493+
-Carbon::parse('2024-01-01');
494+
+Date::now();
495+
+Date::parse('2024-01-01');
496+
```
497+
498+
<br>
499+
500+
```diff
501+
-use Illuminate\Support\Carbon;
502+
+use Illuminate\Support\Facades\Date;
503+
504+
-Carbon::now();
505+
-Carbon::today();
506+
+Date::now();
507+
+Date::today();
508+
```
509+
510+
<br>
511+
482512
## CashierStripeOptionsToStripeRector
483513

484514
Renames the Billable `stripeOptions()` to `stripe().`
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<?php
2+
3+
namespace RectorLaravel\Rector\StaticCall;
4+
5+
use PhpParser\Node;
6+
use PhpParser\Node\Expr\StaticCall;
7+
use PhpParser\Node\Name\FullyQualified;
8+
use PHPStan\Type\ObjectType;
9+
use RectorLaravel\AbstractRector;
10+
use Symplify\RuleDocGenerator\Exception\PoorDocumentationException;
11+
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
12+
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
13+
14+
/**
15+
* @see \RectorLaravel\Tests\Rector\StaticCall\CarbonToDateFacadeRector\CarbonToDateFacadeRectorTest
16+
*/
17+
final class CarbonToDateFacadeRector extends AbstractRector
18+
{
19+
/**
20+
* @throws PoorDocumentationException
21+
*/
22+
public function getRuleDefinition(): RuleDefinition
23+
{
24+
return new RuleDefinition(
25+
'Refactor Carbon static method calls to use the Date facade instead.',
26+
[
27+
new CodeSample(
28+
<<<'CODE_SAMPLE'
29+
use Carbon\Carbon;
30+
31+
Carbon::now();
32+
Carbon::parse('2024-01-01');
33+
CODE_SAMPLE
34+
,
35+
<<<'CODE_SAMPLE'
36+
use Illuminate\Support\Facades\Date;
37+
38+
Date::now();
39+
Date::parse('2024-01-01');
40+
CODE_SAMPLE
41+
),
42+
new CodeSample(
43+
<<<'CODE_SAMPLE'
44+
use Illuminate\Support\Carbon;
45+
46+
Carbon::now();
47+
Carbon::today();
48+
CODE_SAMPLE
49+
,
50+
<<<'CODE_SAMPLE'
51+
use Illuminate\Support\Facades\Date;
52+
53+
Date::now();
54+
Date::today();
55+
CODE_SAMPLE
56+
),
57+
],
58+
);
59+
}
60+
61+
/**
62+
* @return array<class-string<Node>>
63+
*/
64+
public function getNodeTypes(): array
65+
{
66+
return [StaticCall::class];
67+
}
68+
69+
public function refactor(Node $node): ?StaticCall
70+
{
71+
if (! $node instanceof StaticCall) {
72+
return null;
73+
}
74+
75+
if (! $this->isCarbon($node->class)) {
76+
return null;
77+
}
78+
79+
return new StaticCall(
80+
new FullyQualified('Illuminate\Support\Facades\Date'),
81+
$node->name,
82+
$node->args,
83+
$node->getAttributes()
84+
);
85+
}
86+
87+
private function isCarbon(Node $node): bool
88+
{
89+
return $this->isObjectType($node, new ObjectType('Carbon\Carbon')) ||
90+
$this->isObjectType($node, new ObjectType('Illuminate\Support\Carbon'));
91+
}
92+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace RectorLaravel\Tests\Rector\StaticCall\CarbonToDateFacadeRector;
6+
7+
use Iterator;
8+
use PHPUnit\Framework\Attributes\DataProvider;
9+
use Rector\Exception\ShouldNotHappenException;
10+
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
11+
12+
final class CarbonToDateFacadeRectorTest extends AbstractRectorTestCase
13+
{
14+
public static function provideData(): Iterator
15+
{
16+
return self::yieldFilesFromDirectory(__DIR__ . '/Fixture');
17+
}
18+
19+
/**
20+
* @test
21+
*
22+
* @throws ShouldNotHappenException
23+
*/
24+
#[DataProvider('provideData')]
25+
public function test(string $filePath): void
26+
{
27+
$this->doTestFile($filePath);
28+
}
29+
30+
public function provideConfigFilePath(): string
31+
{
32+
return __DIR__ . '/config/configured_rule.php';
33+
}
34+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
namespace RectorLaravel\Tests\Rector\StaticCall\CarbonToDateFacadeRector\Fixture;
4+
5+
use Carbon\Carbon;
6+
7+
class CarbonCarbon
8+
{
9+
public function run()
10+
{
11+
$now = Carbon::now();
12+
$today = Carbon::today();
13+
$yesterday = Carbon::yesterday();
14+
$tomorrow = Carbon::tomorrow();
15+
$parsed = Carbon::parse('2024-01-01');
16+
$created = Carbon::create(2024, 1, 1);
17+
}
18+
}
19+
20+
?>
21+
-----
22+
<?php
23+
24+
namespace RectorLaravel\Tests\Rector\StaticCall\CarbonToDateFacadeRector\Fixture;
25+
26+
use Carbon\Carbon;
27+
28+
class CarbonCarbon
29+
{
30+
public function run()
31+
{
32+
$now = \Illuminate\Support\Facades\Date::now();
33+
$today = \Illuminate\Support\Facades\Date::today();
34+
$yesterday = \Illuminate\Support\Facades\Date::yesterday();
35+
$tomorrow = \Illuminate\Support\Facades\Date::tomorrow();
36+
$parsed = \Illuminate\Support\Facades\Date::parse('2024-01-01');
37+
$created = \Illuminate\Support\Facades\Date::create(2024, 1, 1);
38+
}
39+
}
40+
41+
?>
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
namespace RectorLaravel\Tests\Rector\StaticCall\CarbonToDateFacadeRector\Fixture;
4+
5+
use Illuminate\Support\Carbon;
6+
7+
class IlluminateSupportCarbon
8+
{
9+
public function run()
10+
{
11+
$now = Carbon::now();
12+
$today = Carbon::today();
13+
$parsed = Carbon::parse('2024-01-01');
14+
$created = Carbon::createFromFormat('Y-m-d', '2024-01-01');
15+
}
16+
}
17+
18+
?>
19+
-----
20+
<?php
21+
22+
namespace RectorLaravel\Tests\Rector\StaticCall\CarbonToDateFacadeRector\Fixture;
23+
24+
use Illuminate\Support\Carbon;
25+
26+
class IlluminateSupportCarbon
27+
{
28+
public function run()
29+
{
30+
$now = \Illuminate\Support\Facades\Date::now();
31+
$today = \Illuminate\Support\Facades\Date::today();
32+
$parsed = \Illuminate\Support\Facades\Date::parse('2024-01-01');
33+
$created = \Illuminate\Support\Facades\Date::createFromFormat('Y-m-d', '2024-01-01');
34+
}
35+
}
36+
37+
?>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
namespace RectorLaravel\Tests\Rector\StaticCall\CarbonToDateFacadeRector\Fixture;
4+
5+
use Illuminate\Support\Facades\Date;
6+
7+
class SkipAlreadyUsingDateFacade
8+
{
9+
public function run()
10+
{
11+
// Should not be changed - already using Date facade
12+
$now = Date::now();
13+
}
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
namespace RectorLaravel\Tests\Rector\StaticCall\CarbonToDateFacadeRector\Fixture;
4+
5+
use SomeOther\Carbon;
6+
7+
class SkipNonCarbonClass
8+
{
9+
public function run()
10+
{
11+
// Should not be changed - different Carbon class
12+
$now = Carbon::now();
13+
}
14+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
namespace RectorLaravel\Tests\Rector\StaticCall\CarbonToDateFacadeRector\Fixture;
4+
5+
use Carbon\Carbon;
6+
7+
class WithFullyQualifiedNames
8+
{
9+
public function run()
10+
{
11+
$now = \Carbon\Carbon::now();
12+
$today = \Illuminate\Support\Carbon::today();
13+
}
14+
}
15+
16+
?>
17+
-----
18+
<?php
19+
20+
namespace RectorLaravel\Tests\Rector\StaticCall\CarbonToDateFacadeRector\Fixture;
21+
22+
use Carbon\Carbon;
23+
24+
class WithFullyQualifiedNames
25+
{
26+
public function run()
27+
{
28+
$now = \Illuminate\Support\Facades\Date::now();
29+
$today = \Illuminate\Support\Facades\Date::today();
30+
}
31+
}
32+
33+
?>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Rector\Config\RectorConfig;
6+
use RectorLaravel\Rector\StaticCall\CarbonToDateFacadeRector;
7+
8+
return static function (RectorConfig $rectorConfig): void {
9+
$rectorConfig->import(__DIR__ . '/../../../../../config/config.php');
10+
$rectorConfig->rule(CarbonToDateFacadeRector::class);
11+
};

0 commit comments

Comments
 (0)