-
Notifications
You must be signed in to change notification settings - Fork 9.4k
[GraphQl][GiftMessage] Add functionality for getting message for order item #29417
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
Changes from all commits
4cbb43c
d373aeb
1f27fa7
c2cbea8
21debc0
ef0462c
4343fe2
221df48
2dde101
ccf2225
08ae0ba
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
@@ -0,0 +1,97 @@ | ||||
<?php | ||||
/** | ||||
* Copyright © Magento, Inc. All rights reserved. | ||||
* See COPYING.txt for license details. | ||||
*/ | ||||
declare(strict_types=1); | ||||
|
||||
namespace Magento\GiftMessageGraphQl\Model\Resolver\Order\Item; | ||||
|
||||
use Magento\Framework\Exception\LocalizedException; | ||||
use Magento\Framework\GraphQl\Config\Element\Field; | ||||
use Magento\Framework\GraphQl\Exception\GraphQlInputException; | ||||
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\GiftMessage\Api\OrderItemRepositoryInterface; | ||||
use Magento\GiftMessage\Helper\Message as GiftMessageHelper; | ||||
|
||||
/** | ||||
* Class provides ability to get GiftMessage for order item | ||||
*/ | ||||
class GiftMessage implements ResolverInterface | ||||
{ | ||||
/** | ||||
* @var OrderItemRepositoryInterface | ||||
*/ | ||||
private $orderItemRepository; | ||||
|
||||
/** | ||||
* @var GiftMessageHelper | ||||
*/ | ||||
private $giftMessageHelper; | ||||
|
||||
/** | ||||
* @param OrderItemRepositoryInterface $itemRepository | ||||
* @param GiftMessageHelper $giftMessageHelper | ||||
*/ | ||||
public function __construct( | ||||
OrderItemRepositoryInterface $itemRepository, | ||||
GiftMessageHelper $giftMessageHelper | ||||
) { | ||||
$this->orderItemRepository = $itemRepository; | ||||
$this->giftMessageHelper = $giftMessageHelper; | ||||
} | ||||
|
||||
/** | ||||
* Return information about Gift message for order item | ||||
* | ||||
* @param Field $field | ||||
* @param ContextInterface $context | ||||
* @param ResolveInfo $info | ||||
* @param array|null $value | ||||
* @param array|null $args | ||||
* | ||||
* @return array|Value|mixed | ||||
* @throws GraphQlInputException | ||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter) | ||||
*/ | ||||
public function resolve( | ||||
Field $field, | ||||
$context, | ||||
ResolveInfo $info, | ||||
array $value = null, | ||||
array $args = null | ||||
) { | ||||
if (!isset($value['model'])) { | ||||
throw new GraphQlInputException(__('"model" value must be specified')); | ||||
} | ||||
|
||||
$orderItem = $value['model']; | ||||
|
||||
if (!$this->giftMessageHelper->isMessagesAllowed('items', $orderItem)) { | ||||
return null; | ||||
} | ||||
|
||||
if (!$this->giftMessageHelper->isMessagesAllowed('item', $orderItem)) { | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just want to double-check we really need this part. If we calling
Please, correct me if I'm wrong There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hi @rogyar |
||||
return null; | ||||
} | ||||
|
||||
try { | ||||
$giftItemMessage = $this->orderItemRepository->get($orderItem->getOrderId(), $orderItem->getItemId()); | ||||
} catch (LocalizedException $e) { | ||||
throw new GraphQlInputException(__('Can\'t load message for order item')); | ||||
} | ||||
|
||||
if ($giftItemMessage === null) { | ||||
return null; | ||||
} | ||||
|
||||
return [ | ||||
'to' => $giftItemMessage->getRecipient() ?? '', | ||||
'from' => $giftItemMessage->getSender() ?? '', | ||||
'message'=> $giftItemMessage->getMessage() ?? '' | ||||
]; | ||||
} | ||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
<?php | ||
/** | ||
* Copyright © Magento, Inc. All rights reserved. | ||
* See COPYING.txt for license details. | ||
*/ | ||
declare(strict_types=1); | ||
|
||
namespace Magento\GraphQl\GiftMessage\Order\Item; | ||
|
||
use Exception; | ||
use Magento\Framework\Exception\AuthenticationException; | ||
use Magento\Integration\Api\CustomerTokenServiceInterface; | ||
use Magento\TestFramework\Helper\Bootstrap; | ||
use Magento\TestFramework\TestCase\GraphQlAbstract; | ||
|
||
class GiftMessageTest extends GraphQlAbstract | ||
{ | ||
/** | ||
* @var CustomerTokenServiceInterface | ||
*/ | ||
private $customerTokenService; | ||
|
||
protected function setUp(): void | ||
{ | ||
parent::setUp(); | ||
$this->customerTokenService = Bootstrap::getObjectManager()->get(CustomerTokenServiceInterface::class); | ||
} | ||
|
||
/** | ||
* @magentoConfigFixture default_store sales/gift_options/allow_order 1 | ||
* @magentoConfigFixture default_store sales/gift_options/allow_items 1 | ||
* @magentoApiDataFixture Magento/Customer/_files/customer.php | ||
* @magentoApiDataFixture Magento/GiftMessage/_files/customer/order_with_message.php | ||
* @throws AuthenticationException | ||
* @throws Exception | ||
*/ | ||
public function testGiftMessageForOrderItem() | ||
{ | ||
$query = <<<QUERY | ||
query { | ||
customer { | ||
orders(filter:{number:{eq:"999999991"}}){ | ||
total_count | ||
items { | ||
id | ||
items{ | ||
gift_message { | ||
from | ||
to | ||
message | ||
} | ||
} | ||
gift_message { | ||
from | ||
to | ||
message | ||
} | ||
} | ||
} | ||
} | ||
} | ||
QUERY; | ||
$currentEmail = 'customer@example.com'; | ||
$currentPassword = 'password'; | ||
$response = $this->graphQlQuery($query, [], '', $this->getCustomerAuthHeaders($currentEmail, $currentPassword)); | ||
foreach ($response['customer']['orders']['items'][0]['items'] as $item) { | ||
self::assertArrayHasKey('gift_message', $item); | ||
self::assertSame('Luci', $item['gift_message']['to']); | ||
self::assertSame('Jack', $item['gift_message']['from']); | ||
self::assertSame('Good Job!', $item['gift_message']['message']); | ||
} | ||
} | ||
|
||
/** | ||
* @param string $email | ||
* @param string $password | ||
* @return array | ||
* @throws AuthenticationException | ||
*/ | ||
private function getCustomerAuthHeaders(string $email, string $password): array | ||
{ | ||
$customerToken = $this->customerTokenService->createCustomerAccessToken($email, $password); | ||
return ['Authorization' => 'Bearer ' . $customerToken]; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think that we must be more careful with values provided from FE.
https://3v4l.org/dAvUu
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @rvitaliy
I am sorry but I am not sure that i understand your remark.
Yes, I understood problem which you provided in example but i can't get how it is related with this case in the code.
Perhaps you could explain your point ?
Thanks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
he means if we trust that $value['id'] is a trusted value
and he explained a way to exploit such a value and how it can be misleading using base64_decode
if you wouldn't add this empty line we would of not seen this :)
we actually have a safer way to do this \Magento\Framework\GraphQl\Query\Uid::decode
you can use it if you want, but it's not really the purpose of this PR