@@ -25,10 +25,25 @@ final class ResetPasswordToken
25
25
*/
26
26
private $ expiresAt ;
27
27
28
- public function __construct (string $ token , \DateTimeInterface $ expiresAt )
28
+ /**
29
+ * @var int|null timestamp when the token was created
30
+ */
31
+ private $ generatedAt ;
32
+
33
+ /**
34
+ * @var int expiresAt translator interval
35
+ */
36
+ private $ transInterval = 0 ;
37
+
38
+ public function __construct (string $ token , \DateTimeInterface $ expiresAt , int $ generatedAt = null )
29
39
{
30
40
$ this ->token = $ token ;
31
41
$ this ->expiresAt = $ expiresAt ;
42
+ $ this ->generatedAt = $ generatedAt ;
43
+
44
+ if (null === $ generatedAt ) {
45
+ $ this ->triggerDeprecation ();
46
+ }
32
47
}
33
48
34
49
/**
@@ -47,4 +62,82 @@ public function getExpiresAt(): \DateTimeInterface
47
62
{
48
63
return $ this ->expiresAt ;
49
64
}
65
+
66
+ /**
67
+ * Get the translation message for when a token expires.
68
+ *
69
+ * This is used in conjunction with getExpirationMessageData() method.
70
+ * Example usage in a Twig template:
71
+ *
72
+ * <p>{{ components.expirationMessageKey|trans(components.expirationMessageData) }}</p>
73
+ *
74
+ * symfony/translation is required to translate into a non-English locale.
75
+ *
76
+ * @throws \LogicException
77
+ */
78
+ public function getExpirationMessageKey (): string
79
+ {
80
+ $ interval = $ this ->getExpiresAtIntervalInstance ();
81
+
82
+ switch ($ interval ) {
83
+ case $ interval ->y > 0 :
84
+ $ this ->transInterval = $ interval ->y ;
85
+
86
+ return '%count% year|%count% years ' ;
87
+ case $ interval ->m > 0 :
88
+ $ this ->transInterval = $ interval ->m ;
89
+
90
+ return '%count% month|%count% months ' ;
91
+ case $ interval ->d > 0 :
92
+ $ this ->transInterval = $ interval ->d ;
93
+
94
+ return '%count% day|%count% days ' ;
95
+ case $ interval ->h > 0 :
96
+ $ this ->transInterval = $ interval ->h ;
97
+
98
+ return '%count% hour|%count% hours ' ;
99
+ default :
100
+ $ this ->transInterval = $ interval ->i ;
101
+
102
+ return '%count% minute|%count% minutes ' ;
103
+ }
104
+ }
105
+
106
+ /**
107
+ * @throws \LogicException
108
+ */
109
+ public function getExpirationMessageData (): array
110
+ {
111
+ $ this ->getExpirationMessageKey ();
112
+
113
+ return ['%count% ' => $ this ->transInterval ];
114
+ }
115
+
116
+ /**
117
+ * Get the interval that the token is valid for.
118
+ *
119
+ * @throws \LogicException
120
+ *
121
+ * @psalm-suppress PossiblyFalseArgument
122
+ */
123
+ public function getExpiresAtIntervalInstance (): \DateInterval
124
+ {
125
+ if (null === $ this ->generatedAt ) {
126
+ throw new \LogicException (\sprintf ('%s initialized without setting the $generatedAt timestamp. ' , self ::class));
127
+ }
128
+
129
+ $ createdAtTime = \DateTimeImmutable::createFromFormat ('U ' , (string ) $ this ->generatedAt );
130
+
131
+ return $ this ->expiresAt ->diff ($ createdAtTime );
132
+ }
133
+
134
+ private function triggerDeprecation (): void
135
+ {
136
+ trigger_deprecation (
137
+ 'symfonycasts/reset-password-bundle ' ,
138
+ '1.2 ' ,
139
+ 'Initializing the %s without setting the "$generatedAt" constructor argument is deprecated. The default "null" will be removed in the future. ' ,
140
+ self ::class
141
+ );
142
+ }
50
143
}
0 commit comments