Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Shopify plugin to use GraphQL Admin API #130

Draft
wants to merge 62 commits into
base: 6.x
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
d129ad5
WIP Switch to GQL Admin API
nfourtythree Feb 3, 2025
5ef7ce4
Merge branch '5.x' of github.com:craftcms/shopify into 5.x
nfourtythree Feb 3, 2025
cebaee5
Merge branch '6.x' into feature/pt-2335-shopify-checkout-api-ending-a…
nfourtythree Feb 3, 2025
02a3ae7
Merge branch '6.x' into feature/pt-2335-shopify-checkout-api-ending-a…
nfourtythree Feb 10, 2025
4c4006a
bump deps
nfourtythree Feb 10, 2025
c24bc26
tidy
nfourtythree Feb 10, 2025
c216264
WIP bulk operations syncing
nfourtythree Feb 12, 2025
6542a1a
fix cs
nfourtythree Feb 12, 2025
b07e1ef
remove library
nfourtythree Feb 12, 2025
0d321c6
Remove rogue file
nfourtythree Feb 12, 2025
9739df2
Move to more generic webhook handler
nfourtythree Feb 13, 2025
417818f
Update store data syncing
nfourtythree Feb 13, 2025
05c9bbc
data cleanup on delete of a product
nfourtythree Feb 13, 2025
7dccd94
migrate gid data
nfourtythree Feb 13, 2025
e8bdf8e
Save gid data
nfourtythree Feb 13, 2025
1e419c7
Schema
nfourtythree Feb 13, 2025
81d024b
Update product table joins
nfourtythree Feb 13, 2025
c859706
Add `withMetafields` eager loading to product query
nfourtythree Feb 13, 2025
d896e85
Sync metafield data
nfourtythree Feb 13, 2025
4f8ad81
Fix
nfourtythree Feb 13, 2025
5887363
Add with all and with images eager loading to query
nfourtythree Feb 13, 2025
ab22562
streamline eager loading code
nfourtythree Feb 13, 2025
fa336c9
No need to try and decode things that are decoded
nfourtythree Feb 13, 2025
5b5bd0d
with variants eager loading
nfourtythree Feb 13, 2025
b6ae6ca
Make sure product elements are being created/updated properly
nfourtythree Feb 13, 2025
76a4164
tidy product query
nfourtythree Feb 14, 2025
2e5cd30
Make it easy to create queries
nfourtythree Feb 14, 2025
693c4aa
fix cs
nfourtythree Feb 17, 2025
4428110
Use `publishedOnCurrentPublication` in place of removed `publishedScope`
nfourtythree Feb 17, 2025
7bc7d0a
Make sure there is good backwards compatibility in services
nfourtythree Feb 17, 2025
dc85cdd
Make sure sync’d data is applied
nfourtythree Feb 17, 2025
59aa206
Add bulk op purge
nfourtythree Feb 17, 2025
804a2de
Tidy
nfourtythree Feb 17, 2025
00cdc99
Show bulk op syncs in table
nfourtythree Feb 17, 2025
dffca88
Remove the Product data table
nfourtythree Feb 17, 2025
656241c
Product data table no longer exists
nfourtythree Feb 17, 2025
4367151
extensibility changelog items
nfourtythree Feb 17, 2025
a1e71cc
Remove `API::SHOPIFY_API_VERSION`
nfourtythree Feb 18, 2025
b5b4545
more changelog
nfourtythree Feb 18, 2025
263cfd6
migrate current product data to avoid errors
nfourtythree Feb 19, 2025
371edbc
Change default command action
lukeholder Feb 19, 2025
86baa9e
Various fixes
lukeholder Feb 19, 2025
975f278
fix translations
nfourtythree Feb 19, 2025
3a8450b
move to upgrade md
lukeholder Feb 19, 2025
0257c33
Merge branch 'feature/pt-2335-shopify-checkout-api-ending-april-1-202…
nfourtythree Feb 19, 2025
8bc8337
Move product related methods into products service
nfourtythree Feb 19, 2025
e619733
Remove use
nfourtythree Feb 19, 2025
0b6e2a6
data comparisons
nfourtythree Feb 19, 2025
8c3e1f7
Tidy
nfourtythree Feb 19, 2025
6f82e52
Fix settings parsing and saving
lukeholder Feb 19, 2025
a7b2ad2
settings
nfourtythree Feb 19, 2025
12ab722
Add contextual pricing to products query
nfourtythree Feb 19, 2025
c9a8610
Merge branch 'feature/pt-2335-shopify-checkout-api-ending-april-1-202…
nfourtythree Feb 19, 2025
06c9c7a
more upgrade details
nfourtythree Feb 19, 2025
f41f57b
since tag
nfourtythree Feb 19, 2025
996c565
switch consts to enum
nfourtythree Feb 19, 2025
c9b6249
fixes
nfourtythree Feb 19, 2025
43008f3
Fix enum reference in migrations
AugustMiller Feb 19, 2025
eabe907
Display published status in current channel
lukeholder Feb 20, 2025
948e34c
Fixed a bug where status was returned in graphql in uppercase
lukeholder Feb 20, 2025
9be8888
Use enum colors and CP helper for statuses
nfourtythree Feb 21, 2025
fa0c19f
Add total variants meta data
nfourtythree Feb 24, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 76 additions & 1 deletion CHANGELOG-WIP.md
Original file line number Diff line number Diff line change
@@ -1 +1,76 @@
# Release Notes for Shopify (WIP)
# Release Notes for Shopify (WIP)

> [!IMPORTANT]
> After updating, go to **Shopify** → **Webhooks** and create missing webhooks.

### Extensibility
- Added `craft\shopify\Plugin::getBulkOperation()`.
- Added `craft\shopify\api\BulkDataBatcher`.
- Added `craft\shopify\controllers\Sync`.
- Added `craft\shopify\db\Table::DATA`.
- Added `craft\shopify\db\ProductQuery::$shopifyGid`.
- Added `craft\shopify\db\ProductQuery::shopifyGid()`.
- Added `craft\shopify\db\ProductQuery::$publishedOnCurrentPublication`.
- Added `craft\shopify\db\ProductQuery::publishedOnCurrentPublication()`.
- Added `craft\shopify\db\ProductQuery::$withAll`.
- Added `craft\shopify\db\ProductQuery::$withMetafields`.
- Added `craft\shopify\db\ProductQuery::$withImages`.
- Added `craft\shopify\db\ProductQuery::$withVariants`.
- Added `craft\shopify\db\ProductQuery::withAll()`.
- Added `craft\shopify\db\ProductQuery::withMetafields()`.
- Added `craft\shopify\db\ProductQuery::withImages()`.
- Added `craft\shopify\db\ProductQuery::withVariants()`.
- Added `craft\shopify\elements\Product::$publishedOnCurrentPublication`.
- Added `craft\shopify\elements\Product::$shopifyGid`.
- Added `craft\shopify\elements\Product::getData()`.
- Added `craft\shopify\elements\Product::setData()`.
- Added `craft\shopify\elements\Product::getDescriptionHtml()`.
- Added `craft\shopify\elements\Product::setDescriptionHtml()`.
- Added `craft\shopify\helpers\Product::shopifyStatusHtml()`.
- Added `craft\shopify\helpers\Product::shopifyPublishedHtml()`.
- Added `craft\shopify\jobs\ProcessBulkOperationData`.
- Added `craft\shopify\models\BulkOperation`.
- Added `craft\shopify\records\BulkOperation`.
- Added `craft\shopify\records\ShopifyData`.
- Added `craft\shopify\services\BulkOperations`.
- Added `craft\shopify\services\Api::WEBHOOK_TOPICS`.
- Added `craft\shopify\services\Api::createQuery()`.
- Added `craft\shopify\services\Api::deleteWebhookById()`.
- Added `craft\shopify\services\Api::getGqlClient()`.
- Added `craft\shopify\services\Api::getProductGql()`.
- Added `craft\shopify\services\Api::getShop()`.
- Added `craft\shopify\services\Api::getShopGql()`.
- Added `craft\shopify\services\Api::getShopifyDataByType()`.
- Added `craft\shopify\services\Api::getWebhooks()`.
- Added `craft\shopify\services\Api::query()`.
- Added `craft\shopify\services\Products::eagerLoadImagesForProducts()`.
- Added `craft\shopify\services\Products::eagerLoadMetafieldsForProducts()`.
- Added `craft\shopify\services\Products::eagerLoadVariantsForProducts()`.
- `craft\shopify\events\ShopifyProductSyncEvent::$source` now has a type of `array`.
- `craft\shopify\services\Products::createOrUpdateProduct()`’s `$product` argument now has a type of `array`.
- `craft\shopify\services\Products::createOrUpdateProduct()` no longer has `$metafields` and `$variants` arguments.
- Renamed `craft\shopify\handlers\Product` to `Webhook`.
- Deprecated `craft\shopify\elements\Product::getBodyHtml()`. `getDescriptionHtml()` should be used instead.
- Deprecated `craft\shopify\elements\Product::setBodyHtml()`. `setDescriptionHtml()` should be used instead.
- Deprecated `craft\shopify\elements\Product::getShopifyStatusHtml()`. `craft\shopify\helpers\Product::shopifyStatusHtml()` should be used instead.
- Deprecated `craft\shopify\services\Api::get()`. `query()` should be used instead.
- Deprecated `craft\shopify\services\Api::getAll()`. `query()` should be used instead.
- Deprecated `craft\shopify\services\Api::getAllProducts()`.
- Deprecated `craft\shopify\services\Api::getClient()`. `getGqlClient()` should be used instead.
- Deprecated `craft\shopify\services\Api::getMetafieldsByIdAndOwnerResource()`.
- Deprecated `craft\shopify\services\Api::getMetafieldsByProductId()`.
- Deprecated `craft\shopify\services\Api::getMetafieldsByVariantId()`.
- Deprecated `craft\shopify\services\Api::getProductByShopifyId()`.
- Deprecated `craft\shopify\services\Api::getProductIdByInventoryItemId()`.
- Deprecated `craft\shopify\services\Api::getVariantsByProductId()`.
- Removed `craft\shopify\db\Table::PRODUCTDATA`.
- Removed `craft\shopify\elements\Product::$publishedScope`.
- Removed `craft\shopify\jobs\UpdateProductMetadata`.
- Removed `craft\shopify\records\ProductData`.
- Removed `craft\shopify\services\Api::SHOPIFY_API_VERSION`.
- Removed `craft\shopify\services\Products::$throttle`.
- Removed `craft\shopify\services\Products::$sleepSeconds`.

### System
- Shopify for Craft now uses the GraphQL Admin API to interact with Shopify.
- Data syncing is now done in the queue.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -753,7 +753,7 @@ Event::on(
Products::EVENT_BEFORE_SYNCHRONIZE_PRODUCT,
function(ShopifyProductSyncEvent $event) {
// Example 1: Cancel the sync if a flag is set via a Shopify metafield:
$metafields = $event->element->getMetaFields();
$metafields = $event->element->getMetafields();
if (metafields['do_not_sync'] ?? false) {
$event->isValid = false;
}
Expand Down
285 changes: 285 additions & 0 deletions UPGRADE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,285 @@
## Upgrading from 5.x to 6.x

All json based attributes of the product including:

**product.options**
before
```json
[
{
"id": 8545236451379,
"product_id": 6656149192755,
"name": "Size",
"position": 1,
"values": [
"XX Small",
"X Small",
"Small",
"Medium",
"Large",
"X Large",
"XX Large"
]
},
...
]
```

after
```json
[
{
"id": "gid:\/\/shopify\/ProductOption\/8545236451379",
"name": "Size",
"values": [
"XX Small",
"X Small",
"Small",
"Medium",
"Large",
"X Large",
"XX Large"
],
"position": 1,
"optionValues": [
{
"id": "gid:\/\/shopify\/ProductOptionValue\/79214084147",
"name": "XX Small",
"hasVariants": true
},
{
"id": "gid:\/\/shopify\/ProductOptionValue\/79214116915",
"name": "X Small",
"hasVariants": true
},
{
"id": "gid:\/\/shopify\/ProductOptionValue\/79214149683",
"name": "Small",
"hasVariants": true
},
{
"id": "gid:\/\/shopify\/ProductOptionValue\/79214182451",
"name": "Medium",
"hasVariants": true
},
{
"id": "gid:\/\/shopify\/ProductOptionValue\/79214215219",
"name": "Large",
"hasVariants": true
},
{
"id": "gid:\/\/shopify\/ProductOptionValue\/79214247987",
"name": "X Large",
"hasVariants": true
},
{
"id": "gid:\/\/shopify\/ProductOptionValue\/79214280755",
"name": "XX Large",
"hasVariants": true
}
]
},
...
]
```

**product.variants**
Contextual pricing https://shopify.dev/docs/api/admin-graphql/2025-01/enums/CountryCode
before
```json
[
{
"barcode": "",
"compare_at_price": "21.00",
"created_at": "2022-01-05T14:56:08+00:00",
"fulfillment_service": "manual",
"grams": 0,
"id": 39895248437299,
"image_id": null,
"inventory_item_id": 41993671016499,
"inventory_management": "shopify",
"inventory_policy": "deny",
"inventory_quantity": 6,
"old_inventory_quantity": 6,
"position": 1,
"presentment_prices": [
{
"price": {
"amount": "15.00",
"currency_code": "EUR"
},
"compare_at_price": {
"amount": "21.00",
"currency_code": "EUR"
}
}
],
"price": "15.00",
"product_id": 6656149192755,
"requires_shipping": true,
"sku": "",
"taxable": true,
"title": "XX Small \/ Black \/ Long Sleeve",
"updated_at": "2024-03-28T15:26:13+00:00",
"weight": 0,
"weight_unit": "lb",
"option1": "XX Small",
"option2": "Black",
"option3": "Long Sleeve",
"admin_graphql_api_id": "gid:\/\/shopify\/ProductVariant\/39895248437299",
"metafields": {
"colour": "Black"
}
},
...
]
```

after
```json
[
{
"id": "gid://shopify/ProductVariant/39895248437299",
"sku": "",
"price": "15.00",
"title": "XX Small / Black / Long Sleeve",
"barcode": "",
"product": {
"id": "gid://shopify/Product/6656149192755"
},
"taxable": true,
"createdAt": "2022-01-05T14:56:08Z",
"updatedAt": "2024-03-28T15:26:13Z",
"__parentId": "gid://shopify/Product/6656149192755",
"displayName": "Short Sleeve T-shirt! - XX Small / Black / Long Sleeve",
"inventoryItem": {
"id": "gid://shopify/InventoryItem/41993671016499",
"sku": "",
"tracked": true,
"unitCost": null,
"createdAt": "2022-01-05T14:56:10Z",
"updatedAt": "2022-01-05T14:56:10Z",
"countryCodeOfOrigin": null
},
"compareAtPrice": "21.00",
"inventoryPolicy": "DENY",
"selectedOptions": [
{
"name": "Size",
"value": "XX Small"
},
{
"name": "Colour",
"value": "Black"
},
{
"name": "Style",
"value": "Long Sleeve"
}
],
"inventoryQuantity": 6,
"gbContextualPricing": {
"price": {
"amount": "14.0",
"currencyCode": "GBP"
},
"compareAtPrice": {
"amount": "20.0",
"currencyCode": "GBP"
}
},
"usContextualPricing": {
"price": {
"amount": "15.0",
"currencyCode": "EUR"
},
"compareAtPrice": {
"amount": "21.0",
"currencyCode": "EUR"
}
}
},
...
]
```
**product.images**

before
```json
[
{
"id": 30764054380595,
"alt": null,
"position": 1,
"product_id": 7136056049715,
"created_at": "2024-04-08T13:44:14+01:00",
"updated_at": "2024-04-08T13:44:14+01:00",
"admin_graphql_api_id": "gid:\\/\\/shopify\\/ProductImage\\/30764054380595",
"width": 635,
"height": 560,
"src": "https:\\/\\/cdn.shopify.com\\/s\\/files\\/1\\/0555\\/1672\\/5299\\/files\\/d841f71ea6845bf6005453e15a18c632.jpg?v=1712580254",
"variant_ids": []
},
...
]
```

after
```json
[
{
"id": "gid:\/\/shopify\/MediaImage\/23117921058867",
"alt": "",
"image": {
"url": "https:\/\/cdn.shopify.com\/s\/files\/1\/0555\/1672\/5299\/files\/d841f71ea6845bf6005453e15a18c632.jpg?v=1712580254",
"width": 635,
"height": 560,
"altText": ""
},
"createdAt": "2024-04-08T12:44:14Z",
"updatedAt": "2024-04-08T12:44:14Z",
"__parentId": "gid:\/\/shopify\/Product\/7136056049715",
"mediaContentType": "IMAGE"
},
...
]
```

**product.metafields**
Unchanged

**product.tags**

before
```text
"egnition-sample-data, men, summer, vans"
```

after
```json
[
"egnition-sample-data",
"men",
"summer",
"vans"
]
```

Will have a different structure. For example an option `product_id` is now removed from the options data.

Product element changes:

product.publishedScope removed
product.tags now returns an array of tags instead of a string of comma seperated tags
product.variants is now a relationship
product.images is now a relationship
product.metafields is now a relationship

Settings
Contextual Pricing countries from this list: https://shopify.dev/docs/api/admin-graphql/2025-01/enums/CountryCode

1. upgrade to 6.x (change composer version to 6.0.0)
2. run migrations 'php craft up'
3. re-register webhooks "cp > shopify > webhooks > 'create'"
4. run a full sync again "cp > utilities > Shopify Sync > 'sync all'"
5. Refresh page to monitor progress of sync.
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"prefer-stable": true,
"require": {
"php": "^8.2",
"carnage/php-graphql-client": "^1.14",
"craftcms/cms": "^5.0.0-beta.10||^4.3.0",
"shopify/shopify-api": "^5.2.0"
},
Expand Down
Loading
Loading