22
22
use Pdp \Exception \CouldNotLoadTLDs ;
23
23
use Psr \SimpleCache \CacheInterface ;
24
24
use TypeError ;
25
+ use const DATE_ATOM ;
25
26
use const FILTER_VALIDATE_INT ;
26
27
use const JSON_ERROR_NONE ;
27
28
use function filter_var ;
@@ -77,105 +78,82 @@ public function __construct(CacheInterface $cache, HttpClient $http, $ttl = null
77
78
{
78
79
$ this ->cache = $ cache ;
79
80
$ this ->http = $ http ;
80
- $ this ->ttl = $ this ->setTtl ($ ttl );
81
+ $ this ->ttl = $ this ->filterTtl ($ ttl );
81
82
$ this ->converter = new Converter ();
82
83
}
83
84
84
- /**
85
- * set the cache TTL.
86
- *
87
- * @return DateInterval|null
88
- */
89
- private function setTtl ($ ttl )
90
- {
91
- if ($ ttl instanceof DateInterval || null === $ ttl ) {
92
- return $ ttl ;
93
- }
94
-
95
- if ($ ttl instanceof DateTimeInterface) {
96
- return (new DateTimeImmutable ('now ' , $ ttl ->getTimezone ()))->diff ($ ttl );
97
- }
98
-
99
- if (false !== ($ res = filter_var ($ ttl , FILTER_VALIDATE_INT ))) {
100
- return new DateInterval ('PT ' .$ res .'S ' );
101
- }
102
-
103
- if (is_string ($ ttl )) {
104
- return DateInterval::createFromDateString ($ ttl );
105
- }
106
-
107
- throw new TypeError (sprintf (
108
- 'The ttl must an integer, a string or a DateInterval object %s given ' ,
109
- is_object ($ ttl ) ? get_class ($ ttl ) : gettype ($ ttl )
110
- ));
111
- }
112
-
113
85
/**
114
86
* Gets the Public Suffix List Rules.
115
87
*
88
+ * @param null|mixed $ttl
89
+ *
116
90
* @throws CouldNotLoadRules If the PSL rules can not be loaded
117
91
*/
118
- public function getRules (string $ url = self ::PSL_URL ): Rules
92
+ public function getRules (string $ url = self ::PSL_URL , $ ttl = null ): Rules
119
93
{
120
- $ cacheKey = $ this ->getCacheKey ('PSL ' , $ url );
121
- $ cacheRules = $ this ->cache ->get ($ cacheKey );
94
+ $ key = $ this ->getCacheKey ('PSL ' , $ url );
95
+ $ data = $ this ->cache ->get ($ key );
122
96
123
- if (null === $ cacheRules && !$ this ->refreshRules ($ url )) {
97
+ if (null === $ data && !$ this ->refreshRules ($ url, $ ttl )) {
124
98
throw new CouldNotLoadRules (sprintf ('Unable to load the public suffix list rules for %s ' , $ url ));
125
99
}
126
100
127
- $ rules = json_decode ($ cacheRules ?? $ this ->cache ->get ($ cacheKey ), true );
101
+ $ data = json_decode ($ data ?? $ this ->cache ->get ($ key ), true );
128
102
if (JSON_ERROR_NONE === json_last_error ()) {
129
- return new Rules ($ rules );
103
+ return new Rules ($ data );
130
104
}
131
105
132
106
throw new CouldNotLoadRules ('The public suffix list cache is corrupted: ' .json_last_error_msg (), json_last_error ());
133
107
}
134
108
135
- /**
136
- * Returns the cache key according to the source URL.
137
- */
138
- private function getCacheKey (string $ prefix , string $ str ): string
139
- {
140
- return $ prefix .'_FULL_ ' .md5 (strtolower ($ str ));
141
- }
142
-
143
109
/**
144
110
* Downloads, converts and cache the Public Suffix.
145
111
*
146
112
* If a local cache already exists, it will be overwritten.
147
113
*
148
114
* Returns true if the refresh was successful
115
+ *
116
+ * @param null|mixed $ttl
149
117
*/
150
- public function refreshRules (string $ url = self ::PSL_URL ): bool
118
+ public function refreshRules (string $ url = self ::PSL_URL , $ ttl = null ): bool
151
119
{
152
- $ body = $ this ->http ->getContent ($ url );
153
- $ cacheData = $ this ->converter -> convert ( $ body );
154
- $ cacheKey = $ this ->getCacheKey ( ' PSL ' , $ url ) ;
120
+ $ data = $ this ->converter -> convert ( $ this -> http ->getContent ($ url) );
121
+ $ key = $ this ->getCacheKey ( ' PSL ' , $ url );
122
+ $ ttl = $ this ->filterTtl ( $ ttl ) ?? $ this -> ttl ;
155
123
156
- return $ this ->cache ->set ($ cacheKey , json_encode ($ cacheData ), $ this -> ttl );
124
+ return $ this ->cache ->set ($ key , json_encode ($ data ), $ ttl );
157
125
}
158
126
159
127
/**
160
128
* Gets the Public Suffix List Rules.
161
129
*
130
+ * @param null|mixed $ttl
131
+ *
162
132
* @throws Exception If the Top Level Domains can not be returned
163
133
*/
164
- public function getTLDs (string $ url = self ::RZD_URL ): TopLevelDomains
134
+ public function getTLDs (string $ url = self ::RZD_URL , $ ttl = null ): TopLevelDomains
165
135
{
166
- $ cacheKey = $ this ->getCacheKey ('RZD ' , $ url );
167
- $ cacheList = $ this ->cache ->get ($ cacheKey );
136
+ $ key = $ this ->getCacheKey ('RZD ' , $ url );
137
+ $ data = $ this ->cache ->get ($ key );
168
138
169
- if (null === $ cacheList && !$ this ->refreshTLDs ($ url )) {
139
+ if (null === $ data && !$ this ->refreshTLDs ($ url, $ ttl )) {
170
140
throw new CouldNotLoadTLDs (sprintf ('Unable to load the root zone database from %s ' , $ url ));
171
141
}
172
142
173
- $ data = json_decode ($ cacheList ?? $ this ->cache ->get ($ cacheKey ), true );
174
- if (JSON_ERROR_NONE === json_last_error ()) {
175
- return TopLevelDomains::createFromArray ($ data );
143
+ $ data = json_decode ($ data ?? $ this ->cache ->get ($ key ), true );
144
+ if (JSON_ERROR_NONE !== json_last_error ()) {
145
+ throw new CouldNotLoadTLDs ('The root zone database cache is corrupted: ' .json_last_error_msg (), json_last_error ());
146
+ }
147
+
148
+ if (!isset ($ data ['records ' ], $ data ['version ' ], $ data ['update ' ])) {
149
+ throw new CouldNotLoadTLDs (sprintf ('The root zone database cache content is corrupted ' ));
176
150
}
177
151
178
- throw new CouldNotLoadTLDs ('The root zone database cache is corrupted: ' .json_last_error_msg (), json_last_error ());
152
+ return new TopLevelDomains (
153
+ $ data ['records ' ],
154
+ $ data ['version ' ],
155
+ DateTimeImmutable::createFromFormat (DATE_ATOM , $ data ['update ' ])
156
+ );
179
157
}
180
158
181
159
/**
@@ -185,14 +163,53 @@ public function getTLDs(string $url = self::RZD_URL): TopLevelDomains
185
163
*
186
164
* Returns true if the refresh was successful
187
165
*
166
+ * @param null|mixed $ttl
167
+ *
188
168
* @throws Exception if the source is not validated
189
169
*/
190
- public function refreshTLDs (string $ url = self ::RZD_URL ): bool
170
+ public function refreshTLDs (string $ url = self ::RZD_URL , $ ttl = null ): bool
171
+ {
172
+ $ data = $ this ->converter ->convertRootZoneDatabase ($ this ->http ->getContent ($ url ));
173
+ $ key = $ this ->getCacheKey ('RZD ' , $ url );
174
+ $ ttl = $ this ->filterTtl ($ ttl ) ?? $ this ->ttl ;
175
+
176
+ return $ this ->cache ->set ($ key , json_encode ($ data ), $ ttl );
177
+ }
178
+
179
+ /**
180
+ * set the cache TTL.
181
+ *
182
+ * @return DateInterval|null
183
+ */
184
+ private function filterTtl ($ ttl )
191
185
{
192
- $ body = $ this ->http ->getContent ($ url );
193
- $ cacheData = $ this ->converter ->convertRootZoneDatabase ($ body );
194
- $ cacheKey = $ this ->getCacheKey ('RZD ' , $ url );
186
+ if ($ ttl instanceof DateInterval || null === $ ttl ) {
187
+ return $ ttl ;
188
+ }
189
+
190
+ if ($ ttl instanceof DateTimeInterface) {
191
+ return (new DateTimeImmutable ('now ' , $ ttl ->getTimezone ()))->diff ($ ttl );
192
+ }
193
+
194
+ if (false !== ($ res = filter_var ($ ttl , FILTER_VALIDATE_INT ))) {
195
+ return new DateInterval ('PT ' .$ res .'S ' );
196
+ }
197
+
198
+ if (is_string ($ ttl )) {
199
+ return DateInterval::createFromDateString ($ ttl );
200
+ }
201
+
202
+ throw new TypeError (sprintf (
203
+ 'The ttl must an integer, a string or a DateInterval object %s given ' ,
204
+ is_object ($ ttl ) ? get_class ($ ttl ) : gettype ($ ttl )
205
+ ));
206
+ }
195
207
196
- return $ this ->cache ->set ($ cacheKey , json_encode ($ cacheData ), $ this ->ttl );
208
+ /**
209
+ * Returns the cache key according to the source URL.
210
+ */
211
+ private function getCacheKey (string $ prefix , string $ str ): string
212
+ {
213
+ return sprintf ('%s_FULL_%s ' , $ prefix , md5 (strtolower ($ str )));
197
214
}
198
215
}
0 commit comments