From 017646de97345b1789fed415cd6a8164f7911dcd Mon Sep 17 00:00:00 2001 From: Artjoms Travkovs Date: Fri, 20 Sep 2019 14:48:31 +0300 Subject: [PATCH 01/15] WIP Adding support for configurable products --- composer.json | 4 ++ src/Model/Resolver/AddProductToWishlist.php | 32 ++++++++-- .../Resolver/RemoveProductFromWishlist.php | 2 - src/Model/Resolver/WishlistResolver.php | 60 +++++++++++++++++-- src/etc/schema.graphqls | 15 ++++- 5 files changed, 101 insertions(+), 12 deletions(-) diff --git a/composer.json b/composer.json index c4f990b..69ded58 100644 --- a/composer.json +++ b/composer.json @@ -17,6 +17,10 @@ { "name": "Alfreds Genkins", "email": "alfreds@scandiweb.com" + }, + { + "name": "Artjoms Travkovs", + "email": "artjoms.travkovs@scandiweb.com" } ], "license": [ diff --git a/src/Model/Resolver/AddProductToWishlist.php b/src/Model/Resolver/AddProductToWishlist.php index 9a1a85b..7916237 100644 --- a/src/Model/Resolver/AddProductToWishlist.php +++ b/src/Model/Resolver/AddProductToWishlist.php @@ -16,11 +16,10 @@ namespace ScandiPWA\WishlistGraphQl\Model\Resolver; use Magento\Framework\GraphQl\Config\Element\Field; -use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; -use Magento\Framework\GraphQl\Query\Resolver\Value; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\ConfigurableProduct\Model\Product\Type\Configurable; use Magento\Customer\Api\CustomerRepositoryInterface; use Magento\Wishlist\Model\WishlistFactory; use Magento\Framework\GraphQl\Exception\GraphQlInputException; @@ -79,11 +78,18 @@ public function resolve( throw new GraphQlAuthorizationException(__('Authorization unsuccessful')); } - if (!isset($args['productSku'])) { + [ + 'sku' => $sku, + 'quantity' => $quantity, + 'description' => $description, + 'product_option' => $productOption, + ] = $args['wishlistItem']; + + if (!isset($sku)) { throw new GraphQlInputException(__('Please specify valid product')); } - $product = $this->productRepository->get($args['productSku']); + $product = $this->productRepository->get($sku); if (!$product->isVisibleInCatalog()) { throw new GraphQlInputException(__('Please specify valid product')); } @@ -100,6 +106,14 @@ public function resolve( } $wishlistItem = $wishlist->addNewItem($product); + $wishlistItem->setDescription($description); + $wishlistItem->setQty($quantity); + + if ($product->getTypeId() === Configurable::TYPE_CODE) { + $configurableOptions = $this->getOptionsArray($productOption['extension_attributes']['configurable_item_options']); + $wishlistItem->setOptions($configurableOptions); + } + $wishlist->save(); } catch (Exception $e) { throw new GraphQlNoSuchEntityException(__('There was an error when trying to save wishlist')); @@ -119,4 +133,14 @@ public function resolve( ) ]); } + + private function getOptionsArray($configurableOptions) { + $optionsArray = []; + foreach ($configurableOptions as ['option_id' => $id, 'option_value' => $value]) { + $optionsArray[$id] = $value; + } + + return $optionsArray; + } + } \ No newline at end of file diff --git a/src/Model/Resolver/RemoveProductFromWishlist.php b/src/Model/Resolver/RemoveProductFromWishlist.php index e768880..88b10ad 100644 --- a/src/Model/Resolver/RemoveProductFromWishlist.php +++ b/src/Model/Resolver/RemoveProductFromWishlist.php @@ -16,8 +16,6 @@ namespace ScandiPWA\WishlistGraphQl\Model\Resolver; use Magento\Framework\GraphQl\Config\Element\Field; -use Magento\Framework\GraphQl\Query\Resolver\ContextInterface; -use Magento\Framework\GraphQl\Query\Resolver\Value; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Customer\Api\CustomerRepositoryInterface; diff --git a/src/Model/Resolver/WishlistResolver.php b/src/Model/Resolver/WishlistResolver.php index f4777d3..2302d41 100644 --- a/src/Model/Resolver/WishlistResolver.php +++ b/src/Model/Resolver/WishlistResolver.php @@ -14,15 +14,15 @@ namespace ScandiPWA\WishlistGraphQl\Model\Resolver; +use Magento\Catalog\Model\ProductFactory; +use Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable; + use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Wishlist\Model\ResourceModel\Wishlist as WishlistResourceModel; use Magento\Wishlist\Model\Wishlist; use Magento\Wishlist\Model\WishlistFactory; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; -use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; -use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException; /** * Fetches the Wishlist data according to the GraphQL schema @@ -39,14 +39,31 @@ class WishlistResolver implements ResolverInterface */ private $wishlistFactory; + /** + * @var Configurable + */ + private $configurable; + + /** + * @var ProductFactory + */ + private $productFactory; + /** * @param WishlistResourceModel $wishlistResource * @param WishlistFactory $wishlistFactory */ - public function __construct(WishlistResourceModel $wishlistResource, WishlistFactory $wishlistFactory) + public function __construct( + WishlistResourceModel $wishlistResource, + WishlistFactory $wishlistFactory, + Configurable $configurable, + ProductFactory $productFactory + ) { $this->wishlistResource = $wishlistResource; $this->wishlistFactory = $wishlistFactory; + $this->configurable = $configurable; + $this->productFactory = $productFactory; } /** @@ -71,11 +88,46 @@ public function resolve( ]; } + $itemsData = []; + foreach ($wishlist->getItemCollection() as $item) { + $product = $item->getProduct(); + $parentIds = $this->configurable->getParentIdsByChild($product->getId()); + + print_r($product->getData()); + + if (count($parentIds)) { + $parentProduct = $this->productFactory->create()->load(reset($parentIds)); + $itemsData[] = array_merge( + $item->getData(), + [ + 'product' => array_merge( + $parentProduct->getData(), + ['model' => $parentProduct] + ), + 'sku' => $item->getSku() + ] + ); + } else { + $itemsData[] = array_merge( + $item->getData(), + ['product' => + array_merge( + $product->getData(), + ['model' => $product] + ) + ] + ); + } + } + + exit; + return [ 'sharing_code' => $wishlist->getSharingCode(), 'updated_at' => $wishlist->getUpdatedAt(), 'items_count' => $wishlist->getItemsCount(), 'name' => $wishlist->getName(), + 'items' => $itemsData, 'model' => $wishlist, ]; } diff --git a/src/etc/schema.graphqls b/src/etc/schema.graphqls index 6be1a9d..591fd64 100755 --- a/src/etc/schema.graphqls +++ b/src/etc/schema.graphqls @@ -12,6 +12,17 @@ # See COPYING.txt for license details. type Mutation { - addProductToWishlist(productSku: String!): WishlistItem @resolver(class:"\\ScandiPWA\\WishlistGraphQl\\Model\\Resolver\\AddProductToWishlist") - removeProductFromWishlist(itemId: String!): Boolean @resolver(class:"\\ScandiPWA\\WishlistGraphQl\\Model\\Resolver\\RemoveProductFromWishlist") + addProductToWishlist(wishlistItem: WishlistItemInput!): WishlistItem @doc(description: "Adds product to wish list by its sku") @resolver(class:"\\ScandiPWA\\WishlistGraphQl\\Model\\Resolver\\AddProductToWishlist") + removeProductFromWishlist(itemId: String!): Boolean @doc(description: "Removes product from wish list by its id in it") @resolver(class:"\\ScandiPWA\\WishlistGraphQl\\Model\\Resolver\\RemoveProductFromWishlist") } + +input WishlistItemInput { + sku: String! @doc(description: "Sku of the product") + quantity: Int @doc(description: "Quantity of the product") + description: String @doc(description: "User description of wish list item") + product_option: ProductOptionInput @doc(description: "Configurable product options") +} + +extend type WishlistItem { + sku: String @doc(description: "The wish list item's SKU") +} \ No newline at end of file From 3150439faee8f22163d416ca9f4988d7028d043c Mon Sep 17 00:00:00 2001 From: Artjoms Travkovs Date: Fri, 20 Sep 2019 17:17:51 +0300 Subject: [PATCH 02/15] Implemented adding and retrieving configurable products --- src/Model/Resolver/AddProductToWishlist.php | 24 ++-- src/Model/Resolver/WishlistItemsResolver.php | 128 +++++++++++++++++++ src/Model/Resolver/WishlistResolver.php | 57 +-------- src/etc/di.xml | 2 + 4 files changed, 143 insertions(+), 68 deletions(-) create mode 100644 src/Model/Resolver/WishlistItemsResolver.php diff --git a/src/Model/Resolver/AddProductToWishlist.php b/src/Model/Resolver/AddProductToWishlist.php index 7916237..1167a8d 100644 --- a/src/Model/Resolver/AddProductToWishlist.php +++ b/src/Model/Resolver/AddProductToWishlist.php @@ -78,12 +78,10 @@ public function resolve( throw new GraphQlAuthorizationException(__('Authorization unsuccessful')); } - [ - 'sku' => $sku, - 'quantity' => $quantity, - 'description' => $description, - 'product_option' => $productOption, - ] = $args['wishlistItem']; + ['sku' => $sku] = $args['wishlistItem']; + $quantity = $args['wishlistItem']['quantity'] ?? 1; + $description = $args['wishlistItem']['description'] ?? ''; + $productOption = $args['wishlistItem']['product_option']; if (!isset($sku)) { throw new GraphQlInputException(__('Please specify valid product')); @@ -105,15 +103,17 @@ public function resolve( throw new GraphQlInputException(__('Product has already been added to wishlist')); } - $wishlistItem = $wishlist->addNewItem($product); - $wishlistItem->setDescription($description); - $wishlistItem->setQty($quantity); - + $buyRequest = []; if ($product->getTypeId() === Configurable::TYPE_CODE) { $configurableOptions = $this->getOptionsArray($productOption['extension_attributes']['configurable_item_options']); - $wishlistItem->setOptions($configurableOptions); + $buyRequest['super_attribute'] = $configurableOptions; } + $wishlistItem = $wishlist->addNewItem($product, $buyRequest); + $wishlistItem->setDescription($description); + $wishlistItem->setQty($quantity); + + $wishlist->save(); } catch (Exception $e) { throw new GraphQlNoSuchEntityException(__('There was an error when trying to save wishlist')); @@ -137,7 +137,7 @@ public function resolve( private function getOptionsArray($configurableOptions) { $optionsArray = []; foreach ($configurableOptions as ['option_id' => $id, 'option_value' => $value]) { - $optionsArray[$id] = $value; + $optionsArray[(string) $id] = (int) $value; } return $optionsArray; diff --git a/src/Model/Resolver/WishlistItemsResolver.php b/src/Model/Resolver/WishlistItemsResolver.php new file mode 100644 index 0000000..4510687 --- /dev/null +++ b/src/Model/Resolver/WishlistItemsResolver.php @@ -0,0 +1,128 @@ +wishlistItemCollectionFactory = $wishlistItemCollectionFactory; + $this->storeManager = $storeManager; + $this->productFactory = $productFactory; + } + + /** + * @inheritdoc + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ) { + if (!isset($value['model'])) { + throw new LocalizedException(__('Missing key "model" in Wishlist value data')); + } + /** @var Wishlist $wishlist */ + $wishlist = $value['model']; + + $wishlistItems = $this->getWishListItems($wishlist); + + $data = []; + foreach ($wishlistItems as $wishlistItem) { + $data[] = [ + 'id' => $wishlistItem->getId(), + 'qty' => $wishlistItem->getData('qty'), + 'sku' => $this->getWishListItemSku($wishlistItem), + 'description' => $wishlistItem->getDescription(), + 'added_at' => $wishlistItem->getAddedAt(), + 'model' => $wishlistItem, + ]; + } + return $data; + } + + /** + * Get wishlist items + * + * @param Wishlist $wishlist + * @return Item[] + */ + private function getWishListItems(Wishlist $wishlist): array + { + /** @var WishlistItemCollection $wishlistItemCollection */ + $wishlistItemCollection = $this->wishlistItemCollectionFactory->create(); + $wishlistItemCollection + ->addWishlistFilter($wishlist) + ->addStoreFilter(array_map(function (StoreInterface $store) { + return $store->getId(); + }, $this->storeManager->getStores())) + ->setVisibilityFilter(); + return $wishlistItemCollection->getItems(); + } + + /** + * Get wishlist item's sku + * + * @return string + */ + private function getWishListItemSku($wishlistItem): string + { + $product = $wishlistItem->getProduct(); + $sku = $product->getSku(); + + if ($product->getTypeId() === Configurable::TYPE_CODE) { + $variantId = $wishlistItem->getOptionByCode('simple_product')->getValue(); + $childProduct = $this->productFactory->create()->load($variantId); + $sku = $childProduct->getSku(); + } + + return $sku; + } + +} diff --git a/src/Model/Resolver/WishlistResolver.php b/src/Model/Resolver/WishlistResolver.php index 2302d41..e5c57e6 100644 --- a/src/Model/Resolver/WishlistResolver.php +++ b/src/Model/Resolver/WishlistResolver.php @@ -14,9 +14,6 @@ namespace ScandiPWA\WishlistGraphQl\Model\Resolver; -use Magento\Catalog\Model\ProductFactory; -use Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable; - use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; @@ -39,31 +36,14 @@ class WishlistResolver implements ResolverInterface */ private $wishlistFactory; - /** - * @var Configurable - */ - private $configurable; - - /** - * @var ProductFactory - */ - private $productFactory; - /** * @param WishlistResourceModel $wishlistResource * @param WishlistFactory $wishlistFactory */ - public function __construct( - WishlistResourceModel $wishlistResource, - WishlistFactory $wishlistFactory, - Configurable $configurable, - ProductFactory $productFactory - ) + public function __construct(WishlistResourceModel $wishlistResource, WishlistFactory $wishlistFactory) { $this->wishlistResource = $wishlistResource; $this->wishlistFactory = $wishlistFactory; - $this->configurable = $configurable; - $this->productFactory = $productFactory; } /** @@ -88,46 +68,11 @@ public function resolve( ]; } - $itemsData = []; - foreach ($wishlist->getItemCollection() as $item) { - $product = $item->getProduct(); - $parentIds = $this->configurable->getParentIdsByChild($product->getId()); - - print_r($product->getData()); - - if (count($parentIds)) { - $parentProduct = $this->productFactory->create()->load(reset($parentIds)); - $itemsData[] = array_merge( - $item->getData(), - [ - 'product' => array_merge( - $parentProduct->getData(), - ['model' => $parentProduct] - ), - 'sku' => $item->getSku() - ] - ); - } else { - $itemsData[] = array_merge( - $item->getData(), - ['product' => - array_merge( - $product->getData(), - ['model' => $product] - ) - ] - ); - } - } - - exit; - return [ 'sharing_code' => $wishlist->getSharingCode(), 'updated_at' => $wishlist->getUpdatedAt(), 'items_count' => $wishlist->getItemsCount(), 'name' => $wishlist->getName(), - 'items' => $itemsData, 'model' => $wishlist, ]; } diff --git a/src/etc/di.xml b/src/etc/di.xml index 4541144..21b3ee7 100644 --- a/src/etc/di.xml +++ b/src/etc/di.xml @@ -14,4 +14,6 @@ + From 45de6eaa143b19d65454c5c683f7485e9014a545 Mon Sep 17 00:00:00 2001 From: Artjoms Travkovs Date: Mon, 23 Sep 2019 18:22:18 +0300 Subject: [PATCH 03/15] Fixed product option not being found --- src/Model/Resolver/AddProductToWishlist.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Model/Resolver/AddProductToWishlist.php b/src/Model/Resolver/AddProductToWishlist.php index 1167a8d..1536f8d 100644 --- a/src/Model/Resolver/AddProductToWishlist.php +++ b/src/Model/Resolver/AddProductToWishlist.php @@ -81,7 +81,7 @@ public function resolve( ['sku' => $sku] = $args['wishlistItem']; $quantity = $args['wishlistItem']['quantity'] ?? 1; $description = $args['wishlistItem']['description'] ?? ''; - $productOption = $args['wishlistItem']['product_option']; + $productOption = $args['wishlistItem']['product_option'] ?? []; if (!isset($sku)) { throw new GraphQlInputException(__('Please specify valid product')); From d73c1a880d8bbd1dec4ba9fc4cc2c45c364e1df4 Mon Sep 17 00:00:00 2001 From: Artjoms Travkovs Date: Mon, 23 Sep 2019 18:42:02 +0300 Subject: [PATCH 04/15] Removed incorrectly working exception --- src/Model/Resolver/AddProductToWishlist.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Model/Resolver/AddProductToWishlist.php b/src/Model/Resolver/AddProductToWishlist.php index 1536f8d..5b86a21 100644 --- a/src/Model/Resolver/AddProductToWishlist.php +++ b/src/Model/Resolver/AddProductToWishlist.php @@ -99,10 +99,6 @@ public function resolve( $itemCollection = $wishlist->getItemCollection() ->addFieldToFilter('product_id', $product->getId()); - if ($itemCollection->getSize() > 0) { - throw new GraphQlInputException(__('Product has already been added to wishlist')); - } - $buyRequest = []; if ($product->getTypeId() === Configurable::TYPE_CODE) { $configurableOptions = $this->getOptionsArray($productOption['extension_attributes']['configurable_item_options']); From 6fe3e678201c5cda26b4e402e0da79515a630220 Mon Sep 17 00:00:00 2001 From: Artjoms Travkovs Date: Wed, 25 Sep 2019 18:17:25 +0300 Subject: [PATCH 05/15] Added updateWishlistItem mutation --- src/Model/Resolver/AddProductToWishlist.php | 3 - src/Model/Resolver/UpdateWishlistItem.php | 87 +++++++++++++++++++++ src/etc/schema.graphqls | 1 + 3 files changed, 88 insertions(+), 3 deletions(-) create mode 100644 src/Model/Resolver/UpdateWishlistItem.php diff --git a/src/Model/Resolver/AddProductToWishlist.php b/src/Model/Resolver/AddProductToWishlist.php index 5b86a21..674259e 100644 --- a/src/Model/Resolver/AddProductToWishlist.php +++ b/src/Model/Resolver/AddProductToWishlist.php @@ -96,9 +96,6 @@ public function resolve( $wishlist = $this->wishlistFactory->create(); $wishlist->loadByCustomerId($customerId, true); - $itemCollection = $wishlist->getItemCollection() - ->addFieldToFilter('product_id', $product->getId()); - $buyRequest = []; if ($product->getTypeId() === Configurable::TYPE_CODE) { $configurableOptions = $this->getOptionsArray($productOption['extension_attributes']['configurable_item_options']); diff --git a/src/Model/Resolver/UpdateWishlistItem.php b/src/Model/Resolver/UpdateWishlistItem.php new file mode 100644 index 0000000..8963376 --- /dev/null +++ b/src/Model/Resolver/UpdateWishlistItem.php @@ -0,0 +1,87 @@ +getUserId(); + if ($customerId === null || $customerId === 0) { + throw new GraphQlAuthorizationException(__('Authorization unsuccessful')); + } + + if (!isset($args['itemId'])) { + throw new GraphQlInputException(__('Please specify a valid wishlist item')); + } + + if (!(array_key_exists('quantity', $args) && array_key_exists('description', $args))) { + throw new GraphQlInputException(__('Please specify either quantity or description to update')); + } + + + $item = $this->wishlistItemFactory->create()->load($args['itemId']); + + if (!$item->getId()) { + throw new GraphQlInputException(__('Please specify a valid wishlist item')); + } + + $wishlist = $this->wishlistFactory->create(); + $wishlist->loadByCustomerId($customerId); + if (!$wishlist || $wishlist->getId() !== $item->getWishlistId()) { + throw new GraphQlNoSuchEntityException(__('Invalid wishlist')); + } + + if (array_key_exists('quantity', $args)) { + $item->setQty($args['quantity']); + } + + if (array_key_exists('description', $args)) { + $item->setDescription($args['description']); + } + + try { + $wishlist->save(); + } catch (Exception $e) { + throw new GraphQlNoSuchEntityException(__('There was an error when trying to update wishlist item')); + } + + return array_merge( + $item->getData(), + ['model' => $item] + ); + } + +} diff --git a/src/etc/schema.graphqls b/src/etc/schema.graphqls index 591fd64..8f7230d 100755 --- a/src/etc/schema.graphqls +++ b/src/etc/schema.graphqls @@ -14,6 +14,7 @@ type Mutation { addProductToWishlist(wishlistItem: WishlistItemInput!): WishlistItem @doc(description: "Adds product to wish list by its sku") @resolver(class:"\\ScandiPWA\\WishlistGraphQl\\Model\\Resolver\\AddProductToWishlist") removeProductFromWishlist(itemId: String!): Boolean @doc(description: "Removes product from wish list by its id in it") @resolver(class:"\\ScandiPWA\\WishlistGraphQl\\Model\\Resolver\\RemoveProductFromWishlist") + updateWishlistItem(itemId: String!, quantity: Number, description: String): WishlistItem @doc(description: "Updates wishlist item") @resolver(class: "\\ScandiPWA\\WishlistGraphQl\\Model\\Resolver\\UpdateProductInWishlist") } input WishlistItemInput { From 710babf43041028a94c4188f84fdde2414b9ce9c Mon Sep 17 00:00:00 2001 From: Artjoms Travkovs Date: Wed, 25 Sep 2019 18:42:23 +0300 Subject: [PATCH 06/15] Fixed updateWishlistItem schema --- src/Model/Resolver/UpdateWishlistItem.php | 23 +++++++++++++++++++++-- src/etc/schema.graphqls | 2 +- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/Model/Resolver/UpdateWishlistItem.php b/src/Model/Resolver/UpdateWishlistItem.php index 8963376..a715d7f 100644 --- a/src/Model/Resolver/UpdateWishlistItem.php +++ b/src/Model/Resolver/UpdateWishlistItem.php @@ -15,6 +15,8 @@ namespace ScandiPWA\WishlistGraphQl\Model\Resolver; +use Magento\Wishlist\Model\ItemFactory; +use Magento\Wishlist\Model\WishlistFactory; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; @@ -25,13 +27,30 @@ * Class UpdateProductInWishlist * @package ScandiPWA\WishlistGraphQl\Model\Resolver */ -class UpdateProductInWishlist implements ResolverInterface +class UpdateWishlistItem implements ResolverInterface { + /** + * @var ItemFactory + */ + protected $wishlistItemFactory; + + /** + * @var WishlistFactory + */ + protected $wishlistFactory; + + public function __construct ( + ItemFactory $wishlistItemFactory, + WishlistFactory $wishlistFactory + ) { + $this->wishlistFactory = $wishlistFactory; + $this->wishlistItemFactory = $wishlistItemFactory; + } /** * @inheritDoc */ - public function resolve ( + public function resolve( Field $field, $context, ResolveInfo $info, diff --git a/src/etc/schema.graphqls b/src/etc/schema.graphqls index 8f7230d..fb1ae47 100755 --- a/src/etc/schema.graphqls +++ b/src/etc/schema.graphqls @@ -14,7 +14,7 @@ type Mutation { addProductToWishlist(wishlistItem: WishlistItemInput!): WishlistItem @doc(description: "Adds product to wish list by its sku") @resolver(class:"\\ScandiPWA\\WishlistGraphQl\\Model\\Resolver\\AddProductToWishlist") removeProductFromWishlist(itemId: String!): Boolean @doc(description: "Removes product from wish list by its id in it") @resolver(class:"\\ScandiPWA\\WishlistGraphQl\\Model\\Resolver\\RemoveProductFromWishlist") - updateWishlistItem(itemId: String!, quantity: Number, description: String): WishlistItem @doc(description: "Updates wishlist item") @resolver(class: "\\ScandiPWA\\WishlistGraphQl\\Model\\Resolver\\UpdateProductInWishlist") + updateWishlistItem(itemId: String!, quantity: Int, description: String): WishlistItem @doc(description: "Updates wishlist item") @resolver(class: "\\ScandiPWA\\WishlistGraphQl\\Model\\Resolver\\UpdateWishlistItem") } input WishlistItemInput { From da7369afc45b8a8fe87ea95d52657dd25929fd68 Mon Sep 17 00:00:00 2001 From: Artjoms Travkovs Date: Thu, 26 Sep 2019 20:24:32 +0300 Subject: [PATCH 07/15] Fixed missing argument check && item not saving --- src/Model/Resolver/UpdateWishlistItem.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Model/Resolver/UpdateWishlistItem.php b/src/Model/Resolver/UpdateWishlistItem.php index a715d7f..06b333c 100644 --- a/src/Model/Resolver/UpdateWishlistItem.php +++ b/src/Model/Resolver/UpdateWishlistItem.php @@ -20,8 +20,9 @@ use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; -use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException; +use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; +use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException; /** * Class UpdateProductInWishlist @@ -66,7 +67,7 @@ public function resolve( throw new GraphQlInputException(__('Please specify a valid wishlist item')); } - if (!(array_key_exists('quantity', $args) && array_key_exists('description', $args))) { + if (!(array_key_exists('quantity', $args) || array_key_exists('description', $args))) { throw new GraphQlInputException(__('Please specify either quantity or description to update')); } @@ -92,6 +93,7 @@ public function resolve( } try { + $item->save(); $wishlist->save(); } catch (Exception $e) { throw new GraphQlNoSuchEntityException(__('There was an error when trying to update wishlist item')); From 37b01f535797d68c35d24f4565c21d7aadfc4196 Mon Sep 17 00:00:00 2001 From: Artjoms Travkovs Date: Mon, 30 Sep 2019 04:43:35 +0300 Subject: [PATCH 08/15] Implemented move wishlist to cart functionality --- src/Model/Resolver/AddProductToWishlist.php | 21 +- src/Model/Resolver/MoveWishlistToCart.php | 205 +++++++++++++++++++ src/Model/Resolver/WishlistItemsResolver.php | 11 +- src/etc/schema.graphqls | 1 + 4 files changed, 225 insertions(+), 13 deletions(-) create mode 100644 src/Model/Resolver/MoveWishlistToCart.php diff --git a/src/Model/Resolver/AddProductToWishlist.php b/src/Model/Resolver/AddProductToWishlist.php index 674259e..a57da26 100644 --- a/src/Model/Resolver/AddProductToWishlist.php +++ b/src/Model/Resolver/AddProductToWishlist.php @@ -10,21 +10,20 @@ * @link https://github.com/scandipwa/wishlist-graphql */ -declare(strict_types=1); - +declare (strict_types = 1); namespace ScandiPWA\WishlistGraphQl\Model\Resolver; -use Magento\Framework\GraphQl\Config\Element\Field; -use Magento\Framework\GraphQl\Query\ResolverInterface; -use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\ConfigurableProduct\Model\Product\Type\Configurable; use Magento\Customer\Api\CustomerRepositoryInterface; -use Magento\Wishlist\Model\WishlistFactory; +use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException; use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; -use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException; +use Magento\Framework\GraphQl\Query\ResolverInterface; +use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\Wishlist\Model\WishlistFactory; /** * Class AddWishlistForCustomer @@ -106,7 +105,6 @@ public function resolve( $wishlistItem->setDescription($description); $wishlistItem->setQty($quantity); - $wishlist->save(); } catch (Exception $e) { throw new GraphQlNoSuchEntityException(__('There was an error when trying to save wishlist')); @@ -123,11 +121,12 @@ public function resolve( array_merge( $wishlistItem->getProduct()->getData(), ['model' => $product] - ) + ), ]); } - private function getOptionsArray($configurableOptions) { + private function getOptionsArray($configurableOptions) + { $optionsArray = []; foreach ($configurableOptions as ['option_id' => $id, 'option_value' => $value]) { $optionsArray[(string) $id] = (int) $value; @@ -136,4 +135,4 @@ private function getOptionsArray($configurableOptions) { return $optionsArray; } -} \ No newline at end of file +} diff --git a/src/Model/Resolver/MoveWishlistToCart.php b/src/Model/Resolver/MoveWishlistToCart.php new file mode 100644 index 0000000..d6766bc --- /dev/null +++ b/src/Model/Resolver/MoveWishlistToCart.php @@ -0,0 +1,205 @@ +overriderCartId = $overriderCartId; + $this->quoteRepository = $quoteRepository; + $this->quoteManagement = $quoteManagement; + $this->wishlistFactory = $wishlistFactory; + $this->wishlistResource = $wishlistResource; + } + + /** + * Adds new items from wishlist to cart + * + * @param array $wishlistItems + * @return void + */ + protected function addItemsToCart(array $wishlistItems): void + { + $quoteId = $this->overriderCartId->getOverriddenValue(); + $quote = $this->quoteRepository->getActive($quoteId); + + foreach ($wishlistItems as $item) { + $product = $item['product']; + + $data = []; + if ($product->getTypeId() === Configurable::TYPE_CODE) { + $data['super_attribute'] = $item['super_attribute']; + } + + $buyRequest = new DataObject(); + $buyRequest->setData($data); + + $quoteItem = $quote->addProduct($product, $buyRequest); + $quoteItem->setQty($item['qty']); + } + + try { + $this->quoteRepository->save($quote); + } catch (Exception $e) { + throw new GraphQlNoSuchEntityException(__('There was an error when trying to save wishlist items to cart')); + } + } + + /** + * Cleans wishlist after moving all items to cart + * + * @param Wishlist $wishlist + * @return void + */ + protected function cleanWishlist(Wishlist $wishlist): void + { + $itemsCollection = $wishlist->getItemCollection(); + + foreach ($itemsCollection as $item) { + $item->delete(); + } + + try { + $wishlist->save(); + } catch (Exception $e) { + throw new GraphQlNoSuchEntityException(__('There was an error when trying to clean wishlist')); + } + } + + /** + * Prepares array with wishlist data + * + * @param Wishlist $wishlist + * @return array + */ + protected function getWishlistItems(Wishlist $wishlist): array + { + $items = []; + $itemsCollection = $wishlist->getItemCollection(); + + foreach ($itemsCollection as $item) { + $product = $item->getProduct(); + $superAttribute = $item->getBuyRequest()->getSuperAttribute(); + + $items[$product->getSku()] = [ + 'qty' => $item->getQty(), + 'product' => $product, + 'super_attribute' => $superAttribute, + ]; + } + + return $items; + } + + /** + * @inheritDoc + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ) { + $customerId = $context->getUserId(); + if ($customerId === null || $customerId === 0) { + throw new GraphQlAuthorizationException(__('Authorization unsuccessful')); + } + + $cart = $this->quoteManagement->getCartForCustomer($customerId); + + /** @var Wishlist $wishlist */ + $wishlist = $this->wishlistFactory->create(); + $this->wishlistResource->load($wishlist, $customerId, 'customer_id'); + + if (null === $wishlist->getId() || $wishlist->getItemsCount() <= 0) { + return true; + } + + $wishlistItems = $this->getWishlistItems($wishlist); + $cartItems = $cart->getItems(); + + foreach ($cartItems as $item) { + $product = $item->getProduct(); + $qty = $item->getQty(); + $sku = $product->getSku(); + + if (array_key_exists($sku, $wishlistItems)) { + $wishlistItem = $wishlistItems[$sku]; + unset($wishlistItems[$sku]); + + $qty += $wishlistItem['qty']; + $item->setQty($qty); + } + } + + $this->addItemsToCart($wishlistItems, $cart); + $this->cleanWishlist($wishlist); + + try { + $cart->save(); + } catch (Exception $e) { + throw new GraphQlNoSuchEntityException(__('There was an error when trying to save wishlist items to cart')); + } + + return true; + } +} diff --git a/src/Model/Resolver/WishlistItemsResolver.php b/src/Model/Resolver/WishlistItemsResolver.php index 4510687..fc05e19 100644 --- a/src/Model/Resolver/WishlistItemsResolver.php +++ b/src/Model/Resolver/WishlistItemsResolver.php @@ -1,8 +1,15 @@ Date: Mon, 30 Sep 2019 05:05:11 +0300 Subject: [PATCH 09/15] Implemented wishlist clearing --- src/Model/Resolver/ClearWishlist.php | 84 +++++++++++++++++++++++ src/Model/Resolver/MoveWishlistToCart.php | 1 + src/etc/schema.graphqls | 3 +- 3 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 src/Model/Resolver/ClearWishlist.php diff --git a/src/Model/Resolver/ClearWishlist.php b/src/Model/Resolver/ClearWishlist.php new file mode 100644 index 0000000..717b8db --- /dev/null +++ b/src/Model/Resolver/ClearWishlist.php @@ -0,0 +1,84 @@ +wishlistFactory = $wishlistFactory; + $this->wishlistResource = $wishlistResource; + } + + /** + * @inheritDoc + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ) { + $customerId = $context->getUserId(); + if ($customerId === null || $customerId === 0) { + throw new GraphQlAuthorizationException(__('Authorization unsuccessful')); + } + + /** @var Wishlist $wishlist */ + $wishlist = $this->wishlistFactory->create(); + $this->wishlistResource->load($wishlist, $customerId, 'customer_id'); + + if (null === $wishlist->getId() || $wishlist->getItemsCount() <= 0) { + return true; + } + + $wishlistItems = $wishlist->getItemCollection(); + foreach ($wishlistItems as $item) { + $item->delete(); + } + + try { + $wishlist->save(); + } catch (Exception $e) { + throw new GraphQlNoSuchEntityException(__('There was an error when clearing wishlist')); + } + + return true; + } +} diff --git a/src/Model/Resolver/MoveWishlistToCart.php b/src/Model/Resolver/MoveWishlistToCart.php index d6766bc..2672c97 100644 --- a/src/Model/Resolver/MoveWishlistToCart.php +++ b/src/Model/Resolver/MoveWishlistToCart.php @@ -46,6 +46,7 @@ class MoveWishlistToCart implements ResolverInterface * @var CartManagementInterface */ protected $quoteManagement; + /** * @var WishlistFactory */ diff --git a/src/etc/schema.graphqls b/src/etc/schema.graphqls index ab51937..a17125a 100755 --- a/src/etc/schema.graphqls +++ b/src/etc/schema.graphqls @@ -13,9 +13,10 @@ type Mutation { addProductToWishlist(wishlistItem: WishlistItemInput!): WishlistItem @doc(description: "Adds product to wish list by its sku") @resolver(class:"\\ScandiPWA\\WishlistGraphQl\\Model\\Resolver\\AddProductToWishlist") - moveWishlistToCart: Boolean @doc(description: "Moves items from wishlist to cart") @resolver(class:"ScandiPWA\\WishlistGraphQl\\Model\\Resolver\\MoveWishlistToCart") removeProductFromWishlist(itemId: String!): Boolean @doc(description: "Removes product from wish list by its id in it") @resolver(class:"\\ScandiPWA\\WishlistGraphQl\\Model\\Resolver\\RemoveProductFromWishlist") updateWishlistItem(itemId: String!, quantity: Int, description: String): WishlistItem @doc(description: "Updates wishlist item") @resolver(class: "\\ScandiPWA\\WishlistGraphQl\\Model\\Resolver\\UpdateWishlistItem") + moveWishlistToCart: Boolean @doc(description: "Moves items from wishlist to cart") @resolver(class:"ScandiPWA\\WishlistGraphQl\\Model\\Resolver\\MoveWishlistToCart") + clearWishlist: Boolean @doc(description: "Clears wishlist") @resolver(class: "ScandiPWA\\WishlistGraphQl\\Model\\Resolver\\ClearWishlist") } input WishlistItemInput { From c52e7fb1418154f879c01c9f5d11e1ae66749fd1 Mon Sep 17 00:00:00 2001 From: Artjoms Travkovs Date: Mon, 30 Sep 2019 07:36:06 +0300 Subject: [PATCH 10/15] Improved code quality --- src/Model/Resolver/AddProductToWishlist.php | 10 ++++++---- src/Model/Resolver/ClearWishlist.php | 8 ++++---- src/Model/Resolver/MoveWishlistToCart.php | 2 +- src/Model/Resolver/UpdateWishlistItem.php | 16 +++++++--------- src/Model/Resolver/WishlistItemsResolver.php | 5 ++--- src/etc/schema.graphqls | 2 +- 6 files changed, 21 insertions(+), 22 deletions(-) diff --git a/src/Model/Resolver/AddProductToWishlist.php b/src/Model/Resolver/AddProductToWishlist.php index a57da26..3264dbb 100644 --- a/src/Model/Resolver/AddProductToWishlist.php +++ b/src/Model/Resolver/AddProductToWishlist.php @@ -1,4 +1,5 @@ getData(), ['model' => $wishlistItem], - ['product' => + [ + 'product' => array_merge( $wishlistItem->getProduct()->getData(), ['model' => $product] ), - ]); + ] + ); } private function getOptionsArray($configurableOptions) @@ -134,5 +137,4 @@ private function getOptionsArray($configurableOptions) return $optionsArray; } - } diff --git a/src/Model/Resolver/ClearWishlist.php b/src/Model/Resolver/ClearWishlist.php index 717b8db..c20cdc2 100644 --- a/src/Model/Resolver/ClearWishlist.php +++ b/src/Model/Resolver/ClearWishlist.php @@ -11,19 +11,19 @@ * @link https://github.com/scandipwa/wishlist-graphql */ -declare (strict_types = 1); +declare(strict_types=1); namespace ScandiPWA\WishlistGraphQl\Model\Resolver; use Exception; -use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Config\Element\Field; +use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException; +use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; +use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\Wishlist\Model\ResourceModel\Wishlist as WishlistResourceModel; use Magento\Wishlist\Model\Wishlist; use Magento\Wishlist\Model\WishlistFactory; -use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException; -use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; class ClearWishlist implements ResolverInterface { diff --git a/src/Model/Resolver/MoveWishlistToCart.php b/src/Model/Resolver/MoveWishlistToCart.php index 2672c97..986f1a3 100644 --- a/src/Model/Resolver/MoveWishlistToCart.php +++ b/src/Model/Resolver/MoveWishlistToCart.php @@ -11,7 +11,7 @@ * @link https://github.com/scandipwa/wishlist-graphql */ -declare (strict_types = 1); +declare(strict_types=1); namespace ScandiPWA\WishlistGraphQl\Model\Resolver; diff --git a/src/Model/Resolver/UpdateWishlistItem.php b/src/Model/Resolver/UpdateWishlistItem.php index 06b333c..c1af926 100644 --- a/src/Model/Resolver/UpdateWishlistItem.php +++ b/src/Model/Resolver/UpdateWishlistItem.php @@ -1,4 +1,5 @@ wishlistItemFactory->create()->load($args['itemId']); if (!$item->getId()) { @@ -104,5 +103,4 @@ public function resolve( ['model' => $item] ); } - } diff --git a/src/Model/Resolver/WishlistItemsResolver.php b/src/Model/Resolver/WishlistItemsResolver.php index fc05e19..79edf39 100644 --- a/src/Model/Resolver/WishlistItemsResolver.php +++ b/src/Model/Resolver/WishlistItemsResolver.php @@ -1,4 +1,5 @@ Date: Mon, 30 Sep 2019 07:37:43 +0300 Subject: [PATCH 11/15] spacing fix --- src/Model/Resolver/WishlistItemsResolver.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Model/Resolver/WishlistItemsResolver.php b/src/Model/Resolver/WishlistItemsResolver.php index 79edf39..df6e6ee 100644 --- a/src/Model/Resolver/WishlistItemsResolver.php +++ b/src/Model/Resolver/WishlistItemsResolver.php @@ -91,6 +91,7 @@ public function resolve( 'model' => $wishlistItem, ]; } + return $data; } @@ -110,6 +111,7 @@ private function getWishListItems(Wishlist $wishlist): array return $store->getId(); }, $this->storeManager->getStores())) ->setVisibilityFilter(); + return $wishlistItemCollection->getItems(); } From e47db5b0528de89079541e445c8b353463166d54 Mon Sep 17 00:00:00 2001 From: Artjoms Travkovs Date: Tue, 1 Oct 2019 20:13:51 +0300 Subject: [PATCH 12/15] Updated docs --- README.md | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 60 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 01f5097..9d39d01 100644 --- a/README.md +++ b/README.md @@ -8,9 +8,10 @@ This endpoint allows to add product to Wishlist ```graphql -mutation AddProductToWishlist($productSku: String!) { - addProductToWishlist(productSku: $productSku) { +mutation AddProductToWishlist($wishlistItem: WishlistItemInput!) { + addProductToWishlist(wishlistItem: $wishlistItem) { id + sku qty description added_at @@ -21,13 +22,22 @@ mutation AddProductToWishlist($productSku: String!) { ```json { - "product_sku": "n31189077-1" + "wishlistItem": { + "sku": "n31189077-1", + "quantity": 2, + "description": "Description", + "product_option": { + "extension_attributes": {} + } + } } ``` ### RemoveProductFromWishlist +This endpoint allows removing item from wishlist + ```graphql mutation RemoveProductFromWishlist($item_id: Int!) { removeProductFromWishlist(item_id: $item_id) @@ -39,3 +49,50 @@ mutation RemoveProductFromWishlist($item_id: Int!) { "item_id": 1 } ``` + + +### UpdateWishlistItem + +This endpoint allows to update wishlist item + +```graphql +mutation UpdateWishlistItem($itemId: String!, $quantity: Int, $description: String) { + updateWishlistItem(itemId: $itemId, quantity: $quantity, description: $description) { + id + sku + qty + description + added_at + product + } +} +``` + +```json +{ + "itemId": 1, + "quantity": 2, + "description": "Description" +} +``` + + +### MoveWishlistToCart + +This endpoint allows to move all wishlist items to cart + +```graphql +mutation MoveWishlistToCart { + moveWishlistToCart() +} +``` + +### ClearWishlist + +This endpoint allows to clear wishlist + +```graphql +mutation ClearWishlist { + clearWishlist() +} +``` From 51dcdad4f56f59cf9ff53cdfabc401beeaf30441 Mon Sep 17 00:00:00 2001 From: Artjoms Travkovs Date: Tue, 1 Oct 2019 20:23:22 +0300 Subject: [PATCH 13/15] Fixed some codacy issues --- README.md | 2 -- src/Model/Resolver/WishlistItemsResolver.php | 16 ++++++++-------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 9d39d01..2a8aaea 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,6 @@ mutation RemoveProductFromWishlist($item_id: Int!) { } ``` - ### UpdateWishlistItem This endpoint allows to update wishlist item @@ -76,7 +75,6 @@ mutation UpdateWishlistItem($itemId: String!, $quantity: Int, $description: Stri } ``` - ### MoveWishlistToCart This endpoint allows to move all wishlist items to cart diff --git a/src/Model/Resolver/WishlistItemsResolver.php b/src/Model/Resolver/WishlistItemsResolver.php index df6e6ee..6987134 100644 --- a/src/Model/Resolver/WishlistItemsResolver.php +++ b/src/Model/Resolver/WishlistItemsResolver.php @@ -36,7 +36,7 @@ class WishlistItemsResolver implements ResolverInterface /** * @var WishlistItemCollectionFactory */ - private $wishlistItemCollectionFactory; + private $wishlistItemsFactory; /** * @var StoreManagerInterface @@ -49,15 +49,15 @@ class WishlistItemsResolver implements ResolverInterface private $productFactory; /** - * @param WishlistItemCollectionFactory $wishlistItemCollectionFactory + * @param WishlistItemCollectionFactory $wishlistItemsFactory * @param StoreManagerInterface $storeManager */ public function __construct( - WishlistItemCollectionFactory $wishlistItemCollectionFactory, + WishlistItemCollectionFactory $wishlistItemsFactory, StoreManagerInterface $storeManager, ProductFactory $productFactory ) { - $this->wishlistItemCollectionFactory = $wishlistItemCollectionFactory; + $this->wishlistItemsFactory = $wishlistItemsFactory; $this->storeManager = $storeManager; $this->productFactory = $productFactory; } @@ -103,16 +103,16 @@ public function resolve( */ private function getWishListItems(Wishlist $wishlist): array { - /** @var WishlistItemCollection $wishlistItemCollection */ - $wishlistItemCollection = $this->wishlistItemCollectionFactory->create(); - $wishlistItemCollection + /** @var WishlistItemCollection $collection */ + $collection = $this->wishlistItemsFactory->create(); + $collection ->addWishlistFilter($wishlist) ->addStoreFilter(array_map(function (StoreInterface $store) { return $store->getId(); }, $this->storeManager->getStores())) ->setVisibilityFilter(); - return $wishlistItemCollection->getItems(); + return $collection->getItems(); } /** From c34eefc1a05a11041a27fe30efc166136264fc48 Mon Sep 17 00:00:00 2001 From: Artjoms Travkovs Date: Wed, 16 Oct 2019 00:48:52 +0300 Subject: [PATCH 14/15] Merged update and create wishlist item mutations --- README.md | 35 +----- src/Model/Resolver/ClearWishlist.php | 4 +- src/Model/Resolver/MoveWishlistToCart.php | 2 +- .../Resolver/RemoveProductFromWishlist.php | 2 +- ...Wishlist.php => SaveProductToWishlist.php} | 83 +++++++++++--- src/Model/Resolver/UpdateWishlistItem.php | 106 ------------------ src/Model/Resolver/WishlistItemsResolver.php | 6 +- src/Model/Resolver/WishlistResolver.php | 2 +- src/etc/schema.graphqls | 10 +- 9 files changed, 84 insertions(+), 166 deletions(-) rename src/Model/Resolver/{AddProductToWishlist.php => SaveProductToWishlist.php} (58%) delete mode 100644 src/Model/Resolver/UpdateWishlistItem.php diff --git a/README.md b/README.md index 2a8aaea..fb55ec5 100644 --- a/README.md +++ b/README.md @@ -3,13 +3,13 @@ **WishlistGraphQl** provides additional resolvers for wishlist, extending Magento_WishlistGraphQl. -### AddProductToWishlist +### SaveWishlistItem -This endpoint allows to add product to Wishlist +This endpoint allows to save Wishlist item ```graphql -mutation AddProductToWishlist($wishlistItem: WishlistItemInput!) { - addProductToWishlist(wishlistItem: $wishlistItem) { +mutation SaveWishlistItem($wishlistItem: WishlistItemInput!) { + saveWishlistItem(wishlistItem: $wishlistItem) { id sku qty @@ -39,7 +39,7 @@ mutation AddProductToWishlist($wishlistItem: WishlistItemInput!) { This endpoint allows removing item from wishlist ```graphql -mutation RemoveProductFromWishlist($item_id: Int!) { +mutation RemoveProductFromWishlist($item_id: ID!) { removeProductFromWishlist(item_id: $item_id) } ``` @@ -50,31 +50,6 @@ mutation RemoveProductFromWishlist($item_id: Int!) { } ``` -### UpdateWishlistItem - -This endpoint allows to update wishlist item - -```graphql -mutation UpdateWishlistItem($itemId: String!, $quantity: Int, $description: String) { - updateWishlistItem(itemId: $itemId, quantity: $quantity, description: $description) { - id - sku - qty - description - added_at - product - } -} -``` - -```json -{ - "itemId": 1, - "quantity": 2, - "description": "Description" -} -``` - ### MoveWishlistToCart This endpoint allows to move all wishlist items to cart diff --git a/src/Model/Resolver/ClearWishlist.php b/src/Model/Resolver/ClearWishlist.php index c20cdc2..d0da73e 100644 --- a/src/Model/Resolver/ClearWishlist.php +++ b/src/Model/Resolver/ClearWishlist.php @@ -56,7 +56,7 @@ public function resolve( array $args = null ) { $customerId = $context->getUserId(); - if ($customerId === null || $customerId === 0) { + if (!$customerId) { throw new GraphQlAuthorizationException(__('Authorization unsuccessful')); } @@ -64,7 +64,7 @@ public function resolve( $wishlist = $this->wishlistFactory->create(); $this->wishlistResource->load($wishlist, $customerId, 'customer_id'); - if (null === $wishlist->getId() || $wishlist->getItemsCount() <= 0) { + if (!$wishlist->getId() || $wishlist->getItemsCount() <= 0) { return true; } diff --git a/src/Model/Resolver/MoveWishlistToCart.php b/src/Model/Resolver/MoveWishlistToCart.php index 986f1a3..b46b18f 100644 --- a/src/Model/Resolver/MoveWishlistToCart.php +++ b/src/Model/Resolver/MoveWishlistToCart.php @@ -171,7 +171,7 @@ public function resolve( $wishlist = $this->wishlistFactory->create(); $this->wishlistResource->load($wishlist, $customerId, 'customer_id'); - if (null === $wishlist->getId() || $wishlist->getItemsCount() <= 0) { + if (!$wishlist->getId() || $wishlist->getItemsCount() <= 0) { return true; } diff --git a/src/Model/Resolver/RemoveProductFromWishlist.php b/src/Model/Resolver/RemoveProductFromWishlist.php index 88b10ad..1a82e8b 100644 --- a/src/Model/Resolver/RemoveProductFromWishlist.php +++ b/src/Model/Resolver/RemoveProductFromWishlist.php @@ -73,7 +73,7 @@ public function resolve( array $args = null ) { $customerId = $context->getUserId(); - if ($customerId === null || $customerId === 0) { + if (!$customerId) { throw new GraphQlAuthorizationException(__('There was an issue with authorization')); } diff --git a/src/Model/Resolver/AddProductToWishlist.php b/src/Model/Resolver/SaveProductToWishlist.php similarity index 58% rename from src/Model/Resolver/AddProductToWishlist.php rename to src/Model/Resolver/SaveProductToWishlist.php index 3264dbb..3afc291 100644 --- a/src/Model/Resolver/AddProductToWishlist.php +++ b/src/Model/Resolver/SaveProductToWishlist.php @@ -24,13 +24,14 @@ use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; +use Magento\Wishlist\Model\Wishlist; use Magento\Wishlist\Model\WishlistFactory; /** - * Class AddWishlistForCustomer + * Class SaveProductToWishlist * @package ScandiPWA\WishlistGraphQl\Model\Resolver */ -class AddProductToWishlist implements ResolverInterface +class SaveProductToWishlist implements ResolverInterface { /** * @var ProductRepositoryInterface @@ -48,7 +49,7 @@ class AddProductToWishlist implements ResolverInterface protected $wishlistFactory; /** - * AddWishlistForCustomer constructor. + * SaveProductToWishlist constructor. * @param ProductRepositoryInterface $productRepository * @param CustomerRepositoryInterface $customerRepository * @param WishlistFactory $wishlistFactory @@ -74,35 +75,46 @@ public function resolve( array $args = null ) { $customerId = $context->getUserId(); - if ($customerId === null || $customerId === 0) { + if (!$customerId) { throw new GraphQlAuthorizationException(__('Authorization unsuccessful')); } - ['sku' => $sku] = $args['wishlistItem']; - $quantity = $args['wishlistItem']['quantity'] ?? 1; - $description = $args['wishlistItem']['description'] ?? ''; - $productOption = $args['wishlistItem']['product_option'] ?? []; + $sku = $args['wishlistItem']['sku'] ?? ''; + $itemId = $args['wishlistItem']['item_id'] ?? ''; - if (!isset($sku)) { - throw new GraphQlInputException(__('Please specify valid product')); + $wishlist = $this->wishlistFactory->create(); + $wishlist->loadByCustomerId($customerId, true); + + if ($sku !== '') { + return $this->addProductToWishlist($wishlist, $sku, $args['wishlistItem']); + } + + if ($itemId !== '') { + return $this->updateWishlistItem($wishlist, $itemId, $args['wishlistItem']); } + throw new GraphQlInputException(__('Please specify either sku or item_id')); + } + + protected function addProductToWishlist(Wishlist $wishlist, string $sku, array $parameters) + { + $quantity = $parameters['quantity'] || 1; + $description = $parameters['description'] ?? ''; + $productOption = $parameters['product_option'] ?? []; + $product = $this->productRepository->get($sku); if (!$product->isVisibleInCatalog()) { throw new GraphQlInputException(__('Please specify valid product')); } try { - $wishlist = $this->wishlistFactory->create(); - $wishlist->loadByCustomerId($customerId, true); - - $buyRequest = []; + $configurableData = []; if ($product->getTypeId() === Configurable::TYPE_CODE) { $configurableOptions = $this->getOptionsArray($productOption['extension_attributes']['configurable_item_options']); - $buyRequest['super_attribute'] = $configurableOptions; + $configurableData['super_attribute'] = $configurableOptions; } - $wishlistItem = $wishlist->addNewItem($product, $buyRequest); + $wishlistItem = $wishlist->addNewItem($product, $configurableData); $wishlistItem->setDescription($description); $wishlistItem->setQty($quantity); @@ -128,7 +140,44 @@ public function resolve( ); } - private function getOptionsArray($configurableOptions) + protected function updateWishlistItem(Wishlist $wishlist, string $itemId, array $parameters) + { + if (!(array_key_exists('quantity', $parameters) || array_key_exists('description', $parameters))) { + throw new GraphQlInputException(__('Please specify either quantity or description to update')); + } + + $item = $wishlist->getItem($itemId); + + if (!$item->getId()) { + throw new GraphQlInputException(__('Please specify a valid wishlist item')); + } + + if ($wishlist->getId() !== $item->getWishlistId()) { + throw new GraphQlNoSuchEntityException(__('Invalid wishlist')); + } + + if (array_key_exists('quantity', $parameters)) { + $item->setQty($parameters['quantity']); + } + + if (array_key_exists('description', $parameters)) { + $item->setDescription($parameters['description']); + } + + try { + $item->save(); + $wishlist->save(); + } catch (Exception $e) { + throw new GraphQlNoSuchEntityException(__('There was an error when trying to update wishlist item')); + } + + return array_merge( + $item->getData(), + ['model' => $item] + ); + } + + protected function getOptionsArray(array $configurableOptions) { $optionsArray = []; foreach ($configurableOptions as ['option_id' => $id, 'option_value' => $value]) { diff --git a/src/Model/Resolver/UpdateWishlistItem.php b/src/Model/Resolver/UpdateWishlistItem.php deleted file mode 100644 index c1af926..0000000 --- a/src/Model/Resolver/UpdateWishlistItem.php +++ /dev/null @@ -1,106 +0,0 @@ -wishlistFactory = $wishlistFactory; - $this->wishlistItemFactory = $wishlistItemFactory; - } - - /** - * @inheritDoc - */ - public function resolve( - Field $field, - $context, - ResolveInfo $info, - array $value = null, - array $args = null - ) { - $customerId = $context->getUserId(); - if ($customerId === null || $customerId === 0) { - throw new GraphQlAuthorizationException(__('Authorization unsuccessful')); - } - - if (!isset($args['itemId'])) { - throw new GraphQlInputException(__('Please specify a valid wishlist item')); - } - - if (!(array_key_exists('quantity', $args) || array_key_exists('description', $args))) { - throw new GraphQlInputException(__('Please specify either quantity or description to update')); - } - - $item = $this->wishlistItemFactory->create()->load($args['itemId']); - - if (!$item->getId()) { - throw new GraphQlInputException(__('Please specify a valid wishlist item')); - } - - $wishlist = $this->wishlistFactory->create(); - $wishlist->loadByCustomerId($customerId); - if (!$wishlist || $wishlist->getId() !== $item->getWishlistId()) { - throw new GraphQlNoSuchEntityException(__('Invalid wishlist')); - } - - if (array_key_exists('quantity', $args)) { - $item->setQty($args['quantity']); - } - - if (array_key_exists('description', $args)) { - $item->setDescription($args['description']); - } - - try { - $item->save(); - $wishlist->save(); - } catch (Exception $e) { - throw new GraphQlNoSuchEntityException(__('There was an error when trying to update wishlist item')); - } - - return array_merge( - $item->getData(), - ['model' => $item] - ); - } -} diff --git a/src/Model/Resolver/WishlistItemsResolver.php b/src/Model/Resolver/WishlistItemsResolver.php index 6987134..8fa2ed0 100644 --- a/src/Model/Resolver/WishlistItemsResolver.php +++ b/src/Model/Resolver/WishlistItemsResolver.php @@ -123,14 +123,14 @@ private function getWishListItems(Wishlist $wishlist): array private function getWishListItemSku($wishlistItem): string { $product = $wishlistItem->getProduct(); - $sku = $product->getSku(); if ($product->getTypeId() === Configurable::TYPE_CODE) { $variantId = $wishlistItem->getOptionByCode('simple_product')->getValue(); $childProduct = $this->productFactory->create()->load($variantId); - $sku = $childProduct->getSku(); + + return $childProduct->getSku(); } - return $sku; + return $product->getSku(); } } diff --git a/src/Model/Resolver/WishlistResolver.php b/src/Model/Resolver/WishlistResolver.php index e5c57e6..9403a8f 100644 --- a/src/Model/Resolver/WishlistResolver.php +++ b/src/Model/Resolver/WishlistResolver.php @@ -62,7 +62,7 @@ public function resolve( $wishlist = $this->wishlistFactory->create(); $this->wishlistResource->load($wishlist, $customerId, 'customer_id'); - if (null === $wishlist->getId()) { + if (!$wishlist->getId()) { return [ 'model' => $wishlist, ]; diff --git a/src/etc/schema.graphqls b/src/etc/schema.graphqls index 865daf4..4d49f0e 100755 --- a/src/etc/schema.graphqls +++ b/src/etc/schema.graphqls @@ -12,20 +12,20 @@ # See COPYING.txt for license details. type Mutation { - addProductToWishlist(wishlistItem: WishlistItemInput!): WishlistItem @doc(description: "Adds product to wish list by its sku") @resolver(class:"\\ScandiPWA\\WishlistGraphQl\\Model\\Resolver\\AddProductToWishlist") - removeProductFromWishlist(itemId: String!): Boolean @doc(description: "Removes product from wish list by its id in it") @resolver(class:"\\ScandiPWA\\WishlistGraphQl\\Model\\Resolver\\RemoveProductFromWishlist") - updateWishlistItem(itemId: String!, quantity: Int, description: String): WishlistItem @doc(description: "Updates wishlist item") @resolver(class: "\\ScandiPWA\\WishlistGraphQl\\Model\\Resolver\\UpdateWishlistItem") + saveWishlistItem(wishlistItem: WishlistItemInput!): WishlistItem @doc(description: "Saves wishlist item") @resolver(class:"\\ScandiPWA\\WishlistGraphQl\\Model\\Resolver\\SaveProductToWishlist") + removeProductFromWishlist(itemId: ID!): Boolean @doc(description: "Removes product from wishlist") @resolver(class:"\\ScandiPWA\\WishlistGraphQl\\Model\\Resolver\\RemoveProductFromWishlist") moveWishlistToCart: Boolean @doc(description: "Moves items from wishlist to cart") @resolver(class:"ScandiPWA\\WishlistGraphQl\\Model\\Resolver\\MoveWishlistToCart") clearWishlist: Boolean @doc(description: "Clears wishlist") @resolver(class: "ScandiPWA\\WishlistGraphQl\\Model\\Resolver\\ClearWishlist") } input WishlistItemInput { - sku: String! @doc(description: "Sku of the product") + sku: ID @doc(description: "Sku of the product") + item_id: ID @doc(description: "Id of the wishlist item") quantity: Int @doc(description: "Quantity of the product") description: String @doc(description: "User description of wish list item") product_option: ProductOptionInput @doc(description: "Configurable product options") } extend type WishlistItem { - sku: String @doc(description: "The wish list item's SKU") + sku: ID @doc(description: "The wish list item's SKU") } From a6ea3fdce1bfd7aed9982dda15f3769449e32cbf Mon Sep 17 00:00:00 2001 From: Artjoms Travkovs Date: Wed, 16 Oct 2019 00:58:50 +0300 Subject: [PATCH 15/15] Optimized moving wishlist to cart logic --- src/Model/Resolver/MoveWishlistToCart.php | 25 +++-------------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/src/Model/Resolver/MoveWishlistToCart.php b/src/Model/Resolver/MoveWishlistToCart.php index b46b18f..72c5840 100644 --- a/src/Model/Resolver/MoveWishlistToCart.php +++ b/src/Model/Resolver/MoveWishlistToCart.php @@ -104,27 +104,6 @@ protected function addItemsToCart(array $wishlistItems): void } } - /** - * Cleans wishlist after moving all items to cart - * - * @param Wishlist $wishlist - * @return void - */ - protected function cleanWishlist(Wishlist $wishlist): void - { - $itemsCollection = $wishlist->getItemCollection(); - - foreach ($itemsCollection as $item) { - $item->delete(); - } - - try { - $wishlist->save(); - } catch (Exception $e) { - throw new GraphQlNoSuchEntityException(__('There was an error when trying to clean wishlist')); - } - } - /** * Prepares array with wishlist data * @@ -145,6 +124,8 @@ protected function getWishlistItems(Wishlist $wishlist): array 'product' => $product, 'super_attribute' => $superAttribute, ]; + + $item->delete(); } return $items; @@ -193,9 +174,9 @@ public function resolve( } $this->addItemsToCart($wishlistItems, $cart); - $this->cleanWishlist($wishlist); try { + $wishlist->save(); $cart->save(); } catch (Exception $e) { throw new GraphQlNoSuchEntityException(__('There was an error when trying to save wishlist items to cart'));