@@ -12,6 +12,12 @@ class Api {
1212 private $ client ;
1313 private $ token ;
1414
15+ private $ requests ;
16+ private $ start ;
17+ private $ finish ;
18+
19+ private $ cache = [];
20+
1521 function __construct (
1622 $ token ,
1723 $ version = '1.0.0 '
@@ -23,10 +29,17 @@ function __construct(
2329 $ this ->token = $ token ;
2430 $ this ->version = $ version ;
2531
32+ $ this ->rateRemaining = 60 ;
33+
2634 return $ this ;
2735 }
2836
2937 private function request (string $ path , string $ method , array $ data = []) {
38+ if ($ this ->rateRemaining <= 1 ) {
39+ $ sec = 60 + 30 ;
40+ // echo "Sleeping {$sec}s, X-RateLimit-Remaining: {$this->rateRemaining}", PHP_EOL;
41+ sleep ($ sec );
42+ }
3043 $ curl = curl_init ();
3144 $ options = [
3245 CURLOPT_URL => self ::WEBFLOW_API_ENDPOINT . $ path ,
@@ -38,6 +51,7 @@ private function request(string $path, string $method, array $data = []) {
3851 "Accept: application/json " ,
3952 "Content-Type: application/json " ,
4053 ],
54+ CURLOPT_HEADER => true ,
4155 CURLOPT_RETURNTRANSFER => true ,
4256 ];
4357 if (!empty ($ data )) {
@@ -48,7 +62,21 @@ private function request(string $path, string $method, array $data = []) {
4862 curl_setopt_array ($ curl , $ options );
4963 $ response = curl_exec ($ curl );
5064 curl_close ($ curl );
51- return $ this ->parse ($ response );
65+ list ($ headers , $ body ) = explode ("\r\n\r\n" , $ response , 2 );
66+ $ headers = explode (PHP_EOL , $ headers );
67+ foreach ($ headers as $ header ) {
68+ if (strpos ($ header , ': ' ) > 0 ) {
69+ list ($ headerName , $ headerValue ) = explode (': ' , $ header , 2 );
70+ if ($ headerName == 'X-RateLimit-Limit ' ) {
71+ $ rateLimit = $ headerValue ;
72+ }
73+ if ($ headerName == 'X-RateLimit-Remaining ' ) {
74+ $ rateRemaining = intval ($ headerValue );
75+ }
76+ }
77+ }
78+ $ this ->rateRemaining = $ rateRemaining ?? $ this ->rateRemaining - 1 ;
79+ return $ this ->parse ($ body );
5280
5381 }
5482 private function get ($ path ) {
@@ -68,7 +96,15 @@ private function delete($path, $data) {
6896 }
6997
7098 private function parse ($ response ) {
71- return json_decode ($ response );
99+ $ json = json_decode ($ response );
100+ if (isset ($ json ->code ) && isset ($ json ->msg )) {
101+ $ error = $ json ->msg ;
102+ if (isset ($ json ->problems )) {
103+ $ error .= PHP_EOL . implode (PHP_EOL , $ json ->problems );
104+ }
105+ throw new \Exception ($ error , $ json ->code );
106+ }
107+ return $ json ;
72108 }
73109 // Meta
74110
@@ -130,4 +166,34 @@ public function removeItem(string $collectionId, $itemId) {
130166 return $ this ->delete ("/collections/ {$ collectionId }/items/ {$ itemId }" );
131167 }
132168
169+ public function findOrCreateItemByName (string $ collectionId , array $ fields ) {
170+ if (!isset ($ fields ['name ' ])) {
171+ throw new WebflowException ('name ' );
172+ }
173+ $ cacheKey = "collection- {$ collectionId }-items " ;
174+ $ instance = $ this ;
175+ $ items = $ this ->cache ($ cacheKey , function () use ($ instance , $ collectionId ) {
176+ return $ instance ->items ($ collectionId )->items ;
177+ });
178+ foreach ($ items as $ item ) {
179+ if (strcasecmp ($ item ->name , $ fields ['name ' ]) === 0 ) {
180+ return $ item ;
181+ }
182+ }
183+ $ newItem = $ this ->createItem ($ collectionId , $ fields );
184+ $ items [] = $ newItem ;
185+ $ this ->cacheSet ($ cacheKey , $ items );
186+ return $ newItem ;
187+ }
188+
189+ private function cache ($ key , callable $ callback ) {
190+ if (!isset ($ this ->cache [$ key ])) {
191+ $ this ->cache [$ key ] = $ callback ();
192+ }
193+ return $ this ->cache [$ key ];
194+ }
195+
196+ private function cacheSet ($ key , $ value ) {
197+ $ this ->cache [$ key ] = $ value ;
198+ }
133199}
0 commit comments