From a1179d9cde6eae222ac87496d22c697a8abcce9c Mon Sep 17 00:00:00 2001 From: Toby Allen Date: Fri, 19 Jul 2024 07:33:57 +0100 Subject: [PATCH 01/14] Basic changes required for api v2 to work --- src/Webflow/Api.php | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/Webflow/Api.php b/src/Webflow/Api.php index b9d8e78..226c54b 100644 --- a/src/Webflow/Api.php +++ b/src/Webflow/Api.php @@ -6,7 +6,7 @@ class Api { - const WEBFLOW_API_ENDPOINT = 'https://api.webflow.com'; + const WEBFLOW_API_ENDPOINT = 'https://api.webflow.com/v2'; const WEBFLOW_API_USERAGENT = 'Expertlead Webflow PHP SDK (https://github.com/expertlead/webflow-php-sdk)'; private $client; @@ -59,6 +59,7 @@ private function request(string $path, string $method, array $data = []) $response = curl_exec($curl); curl_close($curl); list($headers, $body) = explode("\r\n\r\n", $response, 2); + ray(['reaspnos body', $body]); return $this->parse($body); } private function get($path) @@ -76,6 +77,12 @@ private function put($path, $data) return $this->request($path, "PUT", $data); } + + private function patch($path, $data) + { + return $this->request($path, "PATCH", $data); + } + private function delete($path) { return $this->request($path, "DELETE"); @@ -145,11 +152,11 @@ public function itemsAll(string $collectionId): array { $response = $this->items($collectionId); $items = $response->items; - $limit = $response->limit; - $total = $response->total; + $limit = $response->pagination->limit; + $total = $response->pagination->total; $pages = ceil($total / $limit); for ($page = 1; $page < $pages; $page++) { - $offset = $response->limit * $page; + $offset = $response->pagination->limit * $page; $items = array_merge($items, $this->items($collectionId, $offset, $limit)->items); } return $items; @@ -174,9 +181,13 @@ public function createItem(string $collectionId, array $fields, bool $live = fal public function updateItem(string $collectionId, string $itemId, array $fields, bool $live = false) { - return $this->put("/collections/{$collectionId}/items/{$itemId}" . ($live ? "?live=true" : ""), [ + // ray(['fields for updateitem', $fields]); + // unset($fields['_id']); + $item =$this->patch("/collections/{$collectionId}/items/{$itemId}" . ($live ? "?live=true" : ""), [ 'fields' => $fields, ]); + //ray(['updateitem', $item]); + return $item; } public function removeItem(string $collectionId, $itemId) From d54fcffcc94decee37974b11634e553fccca2b14 Mon Sep 17 00:00:00 2001 From: Toby Allen Date: Fri, 19 Jul 2024 07:53:25 +0100 Subject: [PATCH 02/14] update field names --- src/Webflow/Api.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Webflow/Api.php b/src/Webflow/Api.php index 226c54b..c32cba8 100644 --- a/src/Webflow/Api.php +++ b/src/Webflow/Api.php @@ -170,8 +170,8 @@ public function item(string $collectionId, string $itemId) public function createItem(string $collectionId, array $fields, bool $live = false) { $defaults = [ - "_archived" => false, - "_draft" => false, + "isArchived" => false, + "isDraft" => false, ]; return $this->post("/collections/{$collectionId}/items" . ($live ? "?live=true" : ""), [ From f23956f9b4f82d9e073720d1f58ed95bba32c09e Mon Sep 17 00:00:00 2001 From: Toby Allen Date: Fri, 19 Jul 2024 20:04:12 +0100 Subject: [PATCH 03/14] updates to fields --- src/Webflow/Api.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Webflow/Api.php b/src/Webflow/Api.php index c32cba8..0b8670e 100644 --- a/src/Webflow/Api.php +++ b/src/Webflow/Api.php @@ -173,10 +173,9 @@ public function createItem(string $collectionId, array $fields, bool $live = fal "isArchived" => false, "isDraft" => false, ]; - - return $this->post("/collections/{$collectionId}/items" . ($live ? "?live=true" : ""), [ - 'fields' => array_merge($defaults, $fields), - ]); + return $this->post("/collections/{$collectionId}/items" . ($live ? "?live=true" : ""), + (object) $fields + ); } public function updateItem(string $collectionId, string $itemId, array $fields, bool $live = false) From 671d7ac15bb828d81186d52852e4a1e1d264b7ad Mon Sep 17 00:00:00 2001 From: Toby Allen Date: Fri, 19 Jul 2024 20:04:28 +0100 Subject: [PATCH 04/14] new publishItem method --- src/Webflow/Api.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/Webflow/Api.php b/src/Webflow/Api.php index 0b8670e..b3a10e1 100644 --- a/src/Webflow/Api.php +++ b/src/Webflow/Api.php @@ -34,7 +34,7 @@ public function __construct( return $this; } - private function request(string $path, string $method, array $data = []) + private function request(string $path, string $method, $data = []) { $curl = curl_init(); $options = [ @@ -52,6 +52,7 @@ private function request(string $path, string $method, array $data = []) ]; if (!empty($data)) { $json = json_encode($data); + $options[CURLOPT_POSTFIELDS] = $json; $options[CURLOPT_HTTPHEADER][] = "Content-Length: " . strlen($json); } @@ -59,7 +60,7 @@ private function request(string $path, string $method, array $data = []) $response = curl_exec($curl); curl_close($curl); list($headers, $body) = explode("\r\n\r\n", $response, 2); - ray(['reaspnos body', $body]); + return $this->parse($body); } private function get($path) @@ -127,6 +128,13 @@ public function publishSite(string $siteId, array $domains) return $this->post("/sites/${siteId}/publish", $domains); } + public function publishItem(string $collection_id, array $itemIds) + { + return $this->post("/collections/{$collection_id}/items/publish", [ + 'itemIds' => $itemIds, + ]); + } + // Collections public function collections(string $siteId) { From e4de9cfcd287719706b0ad9829da565d17200445 Mon Sep 17 00:00:00 2001 From: Toby Allen Date: Fri, 19 Jul 2024 20:05:22 +0100 Subject: [PATCH 05/14] remove comments --- src/Webflow/Api.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Webflow/Api.php b/src/Webflow/Api.php index b3a10e1..0228b23 100644 --- a/src/Webflow/Api.php +++ b/src/Webflow/Api.php @@ -188,12 +188,9 @@ public function createItem(string $collectionId, array $fields, bool $live = fal public function updateItem(string $collectionId, string $itemId, array $fields, bool $live = false) { - // ray(['fields for updateitem', $fields]); - // unset($fields['_id']); $item =$this->patch("/collections/{$collectionId}/items/{$itemId}" . ($live ? "?live=true" : ""), [ 'fields' => $fields, ]); - //ray(['updateitem', $item]); return $item; } From 6c2a99b2b05f5a130ece8c62beea0fb0ce176540 Mon Sep 17 00:00:00 2001 From: Toby Allen Date: Fri, 19 Jul 2024 20:54:27 +0100 Subject: [PATCH 06/14] update item with fieldData --- src/Webflow/Api.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Webflow/Api.php b/src/Webflow/Api.php index 0228b23..8761293 100644 --- a/src/Webflow/Api.php +++ b/src/Webflow/Api.php @@ -188,10 +188,8 @@ public function createItem(string $collectionId, array $fields, bool $live = fal public function updateItem(string $collectionId, string $itemId, array $fields, bool $live = false) { - $item =$this->patch("/collections/{$collectionId}/items/{$itemId}" . ($live ? "?live=true" : ""), [ - 'fields' => $fields, - ]); - return $item; + return $this->patch("/collections/{$collectionId}/items/{$itemId}" . ($live ? "?live=true" : ""), (object) $fields); + } public function removeItem(string $collectionId, $itemId) From 673c5dd8f3c5c00f8ad7187863baeb4686d4b8de Mon Sep 17 00:00:00 2001 From: Toby Allen Date: Sat, 20 Jul 2024 07:01:52 +0100 Subject: [PATCH 07/14] update links --- src/Webflow/Api.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Webflow/Api.php b/src/Webflow/Api.php index 8761293..df340c8 100644 --- a/src/Webflow/Api.php +++ b/src/Webflow/Api.php @@ -6,6 +6,9 @@ class Api { + // changed api endpoints + // https://docs.developers.webflow.com/data/changelog/webflow-api-changed-endpoints + // https://docs.developers.webflow.com/data/reference/ const WEBFLOW_API_ENDPOINT = 'https://api.webflow.com/v2'; const WEBFLOW_API_USERAGENT = 'Expertlead Webflow PHP SDK (https://github.com/expertlead/webflow-php-sdk)'; From 67dfbdef2b451a489cc73b8d2b96fd5d1f24782a Mon Sep 17 00:00:00 2001 From: Toby Allen Date: Sat, 20 Jul 2024 07:10:11 +0100 Subject: [PATCH 08/14] field data in method --- src/Webflow/Api.php | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/Webflow/Api.php b/src/Webflow/Api.php index df340c8..56c5521 100644 --- a/src/Webflow/Api.php +++ b/src/Webflow/Api.php @@ -178,20 +178,30 @@ public function item(string $collectionId, string $itemId) return $this->get("/collections/{$collectionId}/items/{$itemId}"); } - public function createItem(string $collectionId, array $fields, bool $live = false) + public function createItem(string $collectionId, $fields, bool $live = false) { $defaults = [ "isArchived" => false, "isDraft" => false, ]; + $data = (object) [ + 'fieldData' => [], + ]; + $data->fieldData = $fields; return $this->post("/collections/{$collectionId}/items" . ($live ? "?live=true" : ""), - (object) $fields + $data ); + } public function updateItem(string $collectionId, string $itemId, array $fields, bool $live = false) { - return $this->patch("/collections/{$collectionId}/items/{$itemId}" . ($live ? "?live=true" : ""), (object) $fields); + $data = (object) [ + 'fieldData' => [], + ]; + $data->fieldData = $fields; + + return $this->patch("/collections/{$collectionId}/items/{$itemId}" . ($live ? "?live=true" : ""), $data); } From 82f4f8e311e4f3468f1a6729a9c4ed9a912c582f Mon Sep 17 00:00:00 2001 From: Toby Allen Date: Sat, 20 Jul 2024 07:42:07 +0100 Subject: [PATCH 09/14] modify error response. --- src/Webflow/Api.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Webflow/Api.php b/src/Webflow/Api.php index 56c5521..0fa5d69 100644 --- a/src/Webflow/Api.php +++ b/src/Webflow/Api.php @@ -95,12 +95,12 @@ private function delete($path) private function parse($response) { $json = json_decode($response); - if (isset($json->code) && isset($json->msg)) { - $error = $json->msg; - if (isset($json->problems)) { - $error .= PHP_EOL . implode(PHP_EOL, $json->problems); + if (isset($json->code) && isset($json->message)) { + $error = $json->message; + if (isset($json->details)) { + $error .= PHP_EOL . $json->code . ': ' . implode(PHP_EOL, $json->details) ; } - throw new \Exception($error, $json->code); + throw new \Exception($error); } return $json; } From 923dff549601fcc4bed7d15d96bcd1f0d5b3cc00 Mon Sep 17 00:00:00 2001 From: Toby Allen Date: Mon, 22 Jul 2024 18:41:48 +0100 Subject: [PATCH 10/14] publish site correctly --- src/Webflow/Api.php | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/Webflow/Api.php b/src/Webflow/Api.php index 0fa5d69..670eb5e 100644 --- a/src/Webflow/Api.php +++ b/src/Webflow/Api.php @@ -126,9 +126,31 @@ public function domains(string $siteId) return $this->get("/sites/{$siteId}/domains"); } - public function publishSite(string $siteId, array $domains) + /** + * Publish site must take an array list of customdomains to be published to + * and a boolean indicating if your webflow.io subdomain should be published to + * @param string $siteId + * @param array $domains + * @param $publishWebflowSubdomain + * @return mixed + */ + public function publishSite(string $siteId, array $domains, $publishWebflowSubdomain = false) { - return $this->post("/sites/${siteId}/publish", $domains); + if (isset($domains['domains'])){ + // backwards compatibility v1 + $data = ['customDomains' => $domains['domains']]; + } else { + // if domains empty array then + if (!$domains){ + $data = []; + } else { + $data = ['customDomains' => $domains]; + } + } + + $data['publishToWebflowSubdomain'] = $publishWebflowSubdomain; + + return $this->post("/sites/${siteId}/publish", $data); } public function publishItem(string $collection_id, array $itemIds) From a18bafccc32a955c17912f98f42b4364f445dfed Mon Sep 17 00:00:00 2001 From: Toby Allen Date: Mon, 22 Jul 2024 18:42:37 +0100 Subject: [PATCH 11/14] set version --- src/Webflow/Api.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Webflow/Api.php b/src/Webflow/Api.php index 670eb5e..49aa9c9 100644 --- a/src/Webflow/Api.php +++ b/src/Webflow/Api.php @@ -23,7 +23,7 @@ class Api public function __construct( $token, - $version = '1.0.0' + $version = '2.0.0' ) { if (empty($token)) { throw new WebflowException('token'); From ccf9254d9437999b58f74777389ad359225dbc05 Mon Sep 17 00:00:00 2001 From: Toby Allen Date: Mon, 22 Jul 2024 19:13:45 +0100 Subject: [PATCH 12/14] ignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index dd55f33..5c371a2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ composer.phar /vendor/ +/.idea # Commit your application's lock file https://getcomposer.org/doc/01-basic-usage.md#commit-your-composer-lock-file-to-version-control # You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file From 9ac188c7f206a588d73cb12fa75121a1b42c2161 Mon Sep 17 00:00:00 2001 From: Toby Allen Date: Tue, 23 Jul 2024 07:07:13 +0100 Subject: [PATCH 13/14] Domains must be simply an array of domains --- src/Webflow/Api.php | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/Webflow/Api.php b/src/Webflow/Api.php index 49aa9c9..b8eaf59 100644 --- a/src/Webflow/Api.php +++ b/src/Webflow/Api.php @@ -136,18 +136,14 @@ public function domains(string $siteId) */ public function publishSite(string $siteId, array $domains, $publishWebflowSubdomain = false) { - if (isset($domains['domains'])){ - // backwards compatibility v1 - $data = ['customDomains' => $domains['domains']]; + // if domains empty array then + if (!$domains){ + $data = []; } else { - // if domains empty array then - if (!$domains){ - $data = []; - } else { - $data = ['customDomains' => $domains]; - } + $data = ['customDomains' => $domains]; } + $data['publishToWebflowSubdomain'] = $publishWebflowSubdomain; return $this->post("/sites/${siteId}/publish", $data); From 2ae8a9d3dc227c361e43bdd80604d268c1af2ca6 Mon Sep 17 00:00:00 2001 From: Toby Allen Date: Thu, 25 Jul 2024 19:15:50 +0100 Subject: [PATCH 14/14] v2 readme updates --- README.md | 22 ++++++++++++++++++++++ src/Webflow/Api.php | 24 +++++++++++++++++++----- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 9c5cfa3..3157cb8 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,10 @@ Implementation based on [Webflow CMS API Reference](https://developers.webflow.c - Patch Collection Item - Remove Collection Item +## Version 2 + +This package is now using Version 2 of the Webflow Api. + ## Usage Check https://university.webflow.com/article/using-the-webflow-cms-api on how to generate `YOUR_WEBFLOW_API_TOKEN` @@ -68,6 +72,24 @@ $webflow->updateItem($collectionId, $itemId, $fields); $webflow->removeItem($collectionId, $itemId); ``` +## Publising + +### Publishing Items +Publishing an item or items can be done instead of publishing the entire site. +```php +$webflow->publishItem($collectionId, $itemIds); +``` + +### Publishing a Site + +```php +$domains = [$domainID]; +// if you wish to publish to your mydomain.webflow.io subdomain you should specify +// true. If true $domains **must** be an empty array +$publishWebflowSubdomain = true; +$webflow->publishSite($siteId,$domains, $publishWebflowSubdomain) +``` +**nb:** Webflow has very strict limits on publishing your site. Currently 1 per minute. ## Installation diff --git a/src/Webflow/Api.php b/src/Webflow/Api.php index b8eaf59..e2296dc 100644 --- a/src/Webflow/Api.php +++ b/src/Webflow/Api.php @@ -149,6 +149,12 @@ public function publishSite(string $siteId, array $domains, $publishWebflowSubdo return $this->post("/sites/${siteId}/publish", $data); } + /** + * Publish just the items specified, rather than the entire site + * @param string $collection_id + * @param array $itemIds + * @return mixed + */ public function publishItem(string $collection_id, array $itemIds) { return $this->post("/collections/{$collection_id}/items/publish", [ @@ -205,6 +211,7 @@ public function createItem(string $collectionId, $fields, bool $live = false) $data = (object) [ 'fieldData' => [], ]; + // must be an object property $data->fieldData = $fields; return $this->post("/collections/{$collectionId}/items" . ($live ? "?live=true" : ""), $data @@ -212,15 +219,22 @@ public function createItem(string $collectionId, $fields, bool $live = false) } + /** + * Version 2 update item patches the item so you do not need to provide all details. + * @param string $collectionId + * @param string $itemId + * @param array $fields + * @param bool $live + * @return mixed + */ public function updateItem(string $collectionId, string $itemId, array $fields, bool $live = false) { - $data = (object) [ - 'fieldData' => [], - ]; + $data = (object) [ + 'fieldData' => [], + ]; + // must be an object property $data->fieldData = $fields; - return $this->patch("/collections/{$collectionId}/items/{$itemId}" . ($live ? "?live=true" : ""), $data); - } public function removeItem(string $collectionId, $itemId)