Skip to content

Commit dca9b03

Browse files
committed
Merge remote-tracking branch 'honeyb/imported-magento-magento2-30374' into PWA-1303
2 parents 6883714 + 63a7e35 commit dca9b03

File tree

5 files changed

+547
-22
lines changed

5 files changed

+547
-22
lines changed

app/code/Magento/Bundle/Model/Product/BundleOptionDataProvider.php

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use Magento\Bundle\Model\Option;
1212
use Magento\Catalog\Model\Product;
1313
use Magento\Catalog\Model\Product\Configuration\Item\ItemInterface;
14+
use Magento\Framework\GraphQl\Query\Uid;
1415
use Magento\Framework\Pricing\Helper\Data;
1516
use Magento\Framework\Serialize\SerializerInterface;
1617

@@ -19,6 +20,11 @@
1920
*/
2021
class BundleOptionDataProvider
2122
{
23+
/**
24+
* Option type name
25+
*/
26+
private const OPTION_TYPE = 'bundle';
27+
2228
/**
2329
* @var Data
2430
*/
@@ -34,19 +40,27 @@ class BundleOptionDataProvider
3440
*/
3541
private $configuration;
3642

43+
/**
44+
* @var Uid
45+
*/
46+
private $uidEncoder;
47+
3748
/**
3849
* @param Data $pricingHelper
3950
* @param SerializerInterface $serializer
4051
* @param Configuration $configuration
52+
* @param Uid $uidEncoder
4153
*/
4254
public function __construct(
4355
Data $pricingHelper,
4456
SerializerInterface $serializer,
45-
Configuration $configuration
57+
Configuration $configuration,
58+
Uid $uidEncoder
4659
) {
4760
$this->pricingHelper = $pricingHelper;
4861
$this->serializer = $serializer;
4962
$this->configuration = $configuration;
63+
$this->uidEncoder = $uidEncoder;
5064
}
5165

5266
/**
@@ -100,8 +114,15 @@ private function buildBundleOptions(array $bundleOptions, ItemInterface $item):
100114
continue;
101115
}
102116

117+
$optionDetails = [
118+
self::OPTION_TYPE,
119+
$bundleOption->getOptionId()
120+
];
121+
$uidString = implode('/', $optionDetails);
122+
103123
$options[] = [
104124
'id' => $bundleOption->getId(),
125+
'uid' => $this->uidEncoder->encode($uidString),
105126
'label' => $bundleOption->getTitle(),
106127
'type' => $bundleOption->getType(),
107128
'values' => $this->buildBundleOptionValues($bundleOption->getSelections(), $item),
@@ -130,10 +151,19 @@ private function buildBundleOptionValues(array $selections, ItemInterface $item)
130151
continue;
131152
}
132153

154+
$optionValueDetails = [
155+
self::OPTION_TYPE,
156+
$selection->getOptionId(),
157+
$selection->getSelectionId(),
158+
(int) $selection->getSelectionQty()
159+
];
160+
$uidString = implode('/', $optionValueDetails);
161+
133162
$selectionPrice = $this->configuration->getSelectionFinalPrice($item, $selection);
134163
$values[] = [
135-
'label' => $selection->getName(),
136164
'id' => $selection->getSelectionId(),
165+
'uid' => $this->uidEncoder->encode($uidString),
166+
'label' => $selection->getName(),
137167
'quantity' => $qty,
138168
'price' => $this->pricingHelper->currency($selectionPrice, false, false),
139169
];

app/code/Magento/WishlistGraphQl/Model/Resolver/UpdateProductsInWishlist.php

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,26 +10,27 @@
1010
use Magento\Framework\GraphQl\Config\Element\Field;
1111
use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException;
1212
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
13+
use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException;
1314
use Magento\Framework\GraphQl\Query\ResolverInterface;
1415
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
1516
use Magento\Wishlist\Model\ResourceModel\Wishlist as WishlistResourceModel;
1617
use Magento\Wishlist\Model\Wishlist;
1718
use Magento\Wishlist\Model\Wishlist\Config as WishlistConfig;
1819
use Magento\Wishlist\Model\Wishlist\Data\Error;
1920
use Magento\Wishlist\Model\Wishlist\Data\WishlistItemFactory;
20-
use Magento\Wishlist\Model\Wishlist\UpdateProductsInWishlist as UpdateProductsInWishlistModel;
2121
use Magento\Wishlist\Model\WishlistFactory;
2222
use Magento\WishlistGraphQl\Mapper\WishlistDataMapper;
23+
use Magento\WishlistGraphQl\Model\UpdateWishlistItem;
2324

2425
/**
2526
* Update wishlist items resolver
2627
*/
2728
class UpdateProductsInWishlist implements ResolverInterface
2829
{
2930
/**
30-
* @var UpdateProductsInWishlistModel
31+
* @var UpdateWishlistItem
3132
*/
32-
private $updateProductsInWishlist;
33+
private $updateWishlistItem;
3334

3435
/**
3536
* @var WishlistDataMapper
@@ -55,20 +56,20 @@ class UpdateProductsInWishlist implements ResolverInterface
5556
* @param WishlistResourceModel $wishlistResource
5657
* @param WishlistFactory $wishlistFactory
5758
* @param WishlistConfig $wishlistConfig
58-
* @param UpdateProductsInWishlistModel $updateProductsInWishlist
59+
* @param UpdateWishlistItem $updateWishlistItem
5960
* @param WishlistDataMapper $wishlistDataMapper
6061
*/
6162
public function __construct(
6263
WishlistResourceModel $wishlistResource,
6364
WishlistFactory $wishlistFactory,
6465
WishlistConfig $wishlistConfig,
65-
UpdateProductsInWishlistModel $updateProductsInWishlist,
66+
UpdateWishlistItem $updateWishlistItem,
6667
WishlistDataMapper $wishlistDataMapper
6768
) {
6869
$this->wishlistResource = $wishlistResource;
6970
$this->wishlistFactory = $wishlistFactory;
7071
$this->wishlistConfig = $wishlistConfig;
71-
$this->updateProductsInWishlist = $updateProductsInWishlist;
72+
$this->updateWishlistItem = $updateWishlistItem;
7273
$this->wishlistDataMapper = $wishlistDataMapper;
7374
}
7475

@@ -83,34 +84,32 @@ public function resolve(
8384
array $args = null
8485
) {
8586
if (!$this->wishlistConfig->isEnabled()) {
86-
throw new GraphQlInputException(__('The wishlist configuration is currently disabled.'));
87+
throw new GraphQlInputException(__('The wishlist configuration is currently disabled'));
8788
}
8889

8990
$customerId = $context->getUserId();
9091

91-
/* Guest checking */
9292
if (null === $customerId || $customerId === 0) {
9393
throw new GraphQlAuthorizationException(__('The current user cannot perform operations on wishlist'));
9494
}
9595

96-
$wishlistId = ((int) $args['wishlistId']) ?: null;
97-
$wishlist = $this->getWishlist($wishlistId, $customerId);
96+
$wishlist = $this->getWishlist((int) $args['wishlistId'], $customerId);
9897

9998
if (null === $wishlist->getId() || $customerId !== (int) $wishlist->getCustomerId()) {
100-
throw new GraphQlInputException(__('The wishlist was not found.'));
99+
throw new GraphQlInputException(__('Could not find the specified wishlist'));
101100
}
102101

103-
$wishlistItems = $args['wishlistItems'];
104-
$wishlistItems = $this->getWishlistItems($wishlistItems, $wishlist);
105-
$wishlistOutput = $this->updateProductsInWishlist->execute($wishlist, $wishlistItems);
102+
$wishlistItems = $this->getWishlistItems($args['wishlistItems'], $wishlist);
106103

107-
if (count($wishlistOutput->getErrors()) !== count($wishlistItems)) {
108-
$this->wishlistResource->save($wishlist);
104+
foreach ($wishlistItems as $wishlistItem) {
105+
$this->updateWishlistItem->execute($wishlistItem, $wishlist);
109106
}
110107

108+
$wishlistOutput = $this->updateWishlistItem->prepareOutput($wishlist);
109+
111110
return [
112111
'wishlist' => $this->wishlistDataMapper->map($wishlistOutput->getWishlist()),
113-
'user_errors' => \array_map(
112+
'user_errors' => array_map(
114113
function (Error $error) {
115114
return [
116115
'code' => $error->getCode(),
@@ -133,7 +132,6 @@ function (Error $error) {
133132
private function getWishlistItems(array $wishlistItemsData, Wishlist $wishlist): array
134133
{
135134
$wishlistItems = [];
136-
137135
foreach ($wishlistItemsData as $wishlistItemData) {
138136
if (!isset($wishlistItemData['quantity'])) {
139137
$wishlistItem = $wishlist->getItem($wishlistItemData['wishlist_item_id']);
@@ -149,7 +147,6 @@ private function getWishlistItems(array $wishlistItemsData, Wishlist $wishlist):
149147
}
150148
$wishlistItems[] = (new WishlistItemFactory())->create($wishlistItemData);
151149
}
152-
153150
return $wishlistItems;
154151
}
155152

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\WishlistGraphQl\Model;
9+
10+
use Magento\Framework\Exception\AlreadyExistsException;
11+
use Magento\Framework\Exception\LocalizedException;
12+
use Magento\Wishlist\Model\Item;
13+
use Magento\Wishlist\Model\ResourceModel\Wishlist as WishlistResourceModel;
14+
use Magento\Wishlist\Model\Wishlist;
15+
use Magento\Wishlist\Model\Wishlist\BuyRequest\BuyRequestBuilder;
16+
use Magento\Wishlist\Model\Wishlist\Data\Error as WishlistError;
17+
use Magento\Wishlist\Model\Wishlist\Data\WishlistItem as WishlistItemData;
18+
use Magento\Wishlist\Model\Wishlist\Data\WishlistOutput;
19+
20+
/**
21+
* Update wishlist items helper
22+
*/
23+
class UpdateWishlistItem
24+
{
25+
private const ERROR_UNDEFINED = 'UNDEFINED';
26+
27+
/**
28+
* @var WishlistResourceModel
29+
*/
30+
private $wishlistResource;
31+
32+
/**
33+
* @var BuyRequestBuilder
34+
*/
35+
private $buyRequestBuilder;
36+
37+
/**
38+
* @var array
39+
*/
40+
private $errors = [];
41+
42+
/**
43+
* @param WishlistResourceModel $wishlistResource
44+
* @param BuyRequestBuilder $buyRequestBuilder
45+
*/
46+
public function __construct(
47+
WishlistResourceModel $wishlistResource,
48+
BuyRequestBuilder $buyRequestBuilder
49+
) {
50+
$this->wishlistResource = $wishlistResource;
51+
$this->buyRequestBuilder = $buyRequestBuilder;
52+
}
53+
54+
/**
55+
* Update wishlist item and set data from request
56+
*
57+
* @param WishlistItemData $wishlistItemData
58+
* @param Wishlist $wishlist
59+
*
60+
* @throws LocalizedException
61+
* @throws AlreadyExistsException
62+
*/
63+
public function execute(WishlistItemData $wishlistItemData, Wishlist $wishlist)
64+
{
65+
$wishlistItemId = (int) $wishlistItemData->getId();
66+
$wishlistItemToUpdate = $wishlist->getItem($wishlistItemId);
67+
68+
if (!$wishlistItemToUpdate) {
69+
$this->addError(
70+
__('The wishlist item with ID "%1" does not belong to the wishlist', $wishlistItemId)->render()
71+
);
72+
} elseif ((int) $wishlistItemData->getQuantity() === 0) {
73+
$this->addError(
74+
__('The quantity of a wishlist item cannot be 0')->render()
75+
);
76+
} else {
77+
$updatedOptions = $this->getUpdatedOptions($wishlistItemData, $wishlistItemToUpdate);
78+
79+
$wishlistItemToUpdate->setOptions($updatedOptions);
80+
$wishlistItemToUpdate->setQty($wishlistItemData->getQuantity());
81+
if ($wishlistItemData->getDescription()) {
82+
$wishlistItemToUpdate->setDescription($wishlistItemData->getDescription());
83+
}
84+
85+
$this->wishlistResource->save($wishlist);
86+
}
87+
}
88+
89+
/**
90+
* Build the updated options for the specified wishlist item.
91+
*
92+
* @param WishlistItemData $wishlistItemData
93+
* @param Item $wishlistItemToUpdate
94+
* @return array
95+
* @throws LocalizedException
96+
*/
97+
private function getUpdatedOptions(WishlistItemData $wishlistItemData, Item $wishlistItemToUpdate)
98+
{
99+
$wishlistItemId = $wishlistItemToUpdate->getId();
100+
$wishlistItemProduct = $wishlistItemToUpdate->getProduct();
101+
102+
if (!$wishlistItemProduct->getId()) {
103+
throw new LocalizedException(
104+
__('Could not find product for the wishlist item with ID "%1"', $wishlistItemId)
105+
);
106+
}
107+
108+
// Update the buy request using the wishlist item data. Use existing values for unspecified options.
109+
$newBuyRequest = $this->buyRequestBuilder
110+
->build($wishlistItemData)
111+
->setData('action', 'updateItem');
112+
$updatedBuyRequest = $wishlistItemToUpdate->getBuyRequest()->addData($newBuyRequest->toArray());
113+
114+
// Get potential products to add to the cart for the product type using the updated buy request
115+
$wishlistItemProduct->setWishlistStoreId($wishlistItemToUpdate->getStoreId());
116+
$cartCandidates = $wishlistItemProduct->getTypeInstance()->processConfiguration(
117+
$updatedBuyRequest,
118+
clone $wishlistItemProduct
119+
);
120+
121+
if (is_string($cartCandidates)) {
122+
throw new LocalizedException(
123+
__('Could not prepare product for the wishlist item with ID %1', $wishlistItemId)
124+
);
125+
}
126+
127+
// Of the cart candidates, find the parent product and get its options
128+
if (!is_array($cartCandidates)) {
129+
$cartCandidates = [$cartCandidates];
130+
}
131+
$updatedOptions = [];
132+
foreach ($cartCandidates as $candidate) {
133+
if ($candidate->getParentProductId() === null) {
134+
$candidate->setWishlistStoreId($wishlistItemToUpdate->getStoreId());
135+
$updatedOptions = $candidate->getCustomOptions();
136+
break;
137+
}
138+
}
139+
140+
return $updatedOptions;
141+
}
142+
143+
/**
144+
* Add wishlist line item error
145+
*
146+
* @param string $message
147+
* @param string|null $code
148+
*
149+
* @return void
150+
*/
151+
private function addError(string $message, string $code = null): void
152+
{
153+
$this->errors[] = new WishlistError(
154+
$message,
155+
$code ?? self::ERROR_UNDEFINED
156+
);
157+
}
158+
159+
/**
160+
* Prepare output
161+
*
162+
* @param Wishlist $wishlist
163+
*
164+
* @return WishlistOutput
165+
*/
166+
public function prepareOutput(Wishlist $wishlist): WishlistOutput
167+
{
168+
$output = new WishlistOutput($wishlist, $this->errors);
169+
$this->errors = [];
170+
171+
return $output;
172+
}
173+
}

0 commit comments

Comments
 (0)