From 76a7243995ce3d6ba205df8386da6c6d392b71dd Mon Sep 17 00:00:00 2001 From: Ronak Patel Date: Sun, 21 Oct 2018 12:45:04 +0530 Subject: [PATCH 01/14] Fixed - Total pages field returns null in category query --- .../CatalogGraphQl/Model/Resolver/Category/Products.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Products.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Products.php index 557c7e08ff432..7a41f8fc94e74 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Products.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Products.php @@ -92,7 +92,8 @@ public function resolve( 'items' => $searchResult->getProductsSearchResult(), 'page_info' => [ 'page_size' => $searchCriteria->getPageSize(), - 'current_page' => $currentPage + 'current_page' => $currentPage, + 'total_pages' => $maxPages ] ]; return $data; From 505ac52e2a242555873545faced2eef0a275fe4e Mon Sep 17 00:00:00 2001 From: Tobias Maile Date: Fri, 26 Oct 2018 16:55:02 +0200 Subject: [PATCH 02/14] GraphQL-202: [Mutations] adds sendEmailFriend Logic --- .../Model/Resolver/SendEmailToFriend.php | 147 ++++++++++++++++++ .../Magento/SendFriendGraphQl/etc/module.xml | 11 ++ .../SendFriendGraphQl/etc/schema.graphqls | 33 ++++ .../SendFriendGraphQl/registration.php | 9 ++ 4 files changed, 200 insertions(+) create mode 100644 app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php create mode 100644 app/code/Magento/SendFriendGraphQl/etc/module.xml create mode 100644 app/code/Magento/SendFriendGraphQl/etc/schema.graphqls create mode 100644 app/code/Magento/SendFriendGraphQl/registration.php diff --git a/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php b/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php new file mode 100644 index 0000000000000..56f6d20b20f18 --- /dev/null +++ b/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php @@ -0,0 +1,147 @@ +sendFriend = $sendFriend; + $this->productRepository = $productRepository; + $this->dataObjectFactory = $dataObjectFactory; + } + + /** + * @inheritdoc + */ + public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) + { + if ($this->sendFriend->getMaxSendsToFriend() && $this->sendFriend->isExceedLimit()) { + throw new GraphQlInputException(__('You can\'t send messages more than %1 times an hour.', + $this->sendFriend->getMaxSendsToFriend() + )); + } + + $product = $this->getProductFromRepository($args['input']['params']['product_id']); + $senderArray = $this->getSenderArrayFromArgs($args); + $recipientsArray = $this->getRecipientsArray($args); + //@todo clarify if event should be dispatched + //$this->_eventManager->dispatch('sendfriend_product', ['product' => $product]); + $this->sendFriend->setSender($senderArray); + $this->sendFriend->setRecipients($recipientsArray); + $this->sendFriend->setProduct($product); + + $this->prepareDataForValidation($args, $recipientsArray); + $validationResult = $this->sendFriend->validate(); + $this->addRecipientNameValidation($args); + if ($validationResult !== true) { + throw new GraphQlInputException(__(implode($validationResult))); + } + + $this->sendFriend->send(); + + return array_merge($senderArray, $recipientsArray); + } + + private function prepareDataForValidation(array $args, array $recipientsArray): void + { + $sender = $this->dataObjectFactory->create()->setData([ + 'name' => $args['input']['sender']['name'], + 'email'=> $args['input']['sender']['email'], + 'message' => $args['input']['sender']['message'], + ]); + $emails = []; + foreach ($recipientsArray['recipients'] as $recipient) { + $emails[] = $recipient['email']; + } + $recipients = $this->dataObjectFactory->create()->setData('emails', $emails); + + $this->sendFriend->setData('_sender', $sender); + $this->sendFriend->setData('_recipients', $recipients); + } + + /** + * @param array $args + * @throws GraphQlInputException + */ + private function addRecipientNameValidation(array $args): void + { + foreach ($args['input']['recipients'] as $recipient) { + if (empty($recipient['name'])) { + throw new GraphQlInputException( + __('Please Provide Name for Recipient with this Email Address: ' . $recipient['email'] + )); + } + } + } + + /** + * @param int $productId + * @return bool|\Magento\Catalog\Api\Data\ProductInterface + */ + private function getProductFromRepository(int $productId) + { + try { + $product = $this->productRepository->getById($productId); + if (!$product->isVisibleInCatalog()) { + return false; + } + } catch (NoSuchEntityException $noEntityException) { + return false; + } + + return $product; + } + + private function getRecipientsArray(array $args): array + { + $recipientsArray = []; + foreach ($args['input']['recipients'] as $recipient) { + $recipientsArray[] = [ + 'name' => $recipient['name'], + 'email' => $recipient['email'], + ]; + } + return ['recipients' => $recipientsArray]; + } + + private function getSenderArrayFromArgs(array $args): array + { + return ['sender' => [ + 'name' => $args['input']['sender']['name'], + 'email' => $args['input']['sender']['email'], + 'message' => $args['input']['sender']['message'], + ] + ]; + } +} diff --git a/app/code/Magento/SendFriendGraphQl/etc/module.xml b/app/code/Magento/SendFriendGraphQl/etc/module.xml new file mode 100644 index 0000000000000..14d792198cd5f --- /dev/null +++ b/app/code/Magento/SendFriendGraphQl/etc/module.xml @@ -0,0 +1,11 @@ + + + + + diff --git a/app/code/Magento/SendFriendGraphQl/etc/schema.graphqls b/app/code/Magento/SendFriendGraphQl/etc/schema.graphqls new file mode 100644 index 0000000000000..87bf90fd10072 --- /dev/null +++ b/app/code/Magento/SendFriendGraphQl/etc/schema.graphqls @@ -0,0 +1,33 @@ +# Copyright © Magento, Inc. All rights reserved. +# See COPYING.txt for license details. + +type Mutation { + sendEmailToFriend (input: SendEmailToFriendSenderInput): SendEmailToFriendOutput @resolver(class: "\\Magento\\SendFriendGraphQl\\Model\\Resolver\\SendEmailToFriend") @doc(description:"@todo") +} + +input SendEmailToFriendSenderInput { + sender: Sender! + params: Params! + recipients: [Recipient] +} + +type Sender { + name: String! + email: String! + message: String! +} +#@todo Prams can be removed if dispatching of event in app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php not needed +type Params { + product_id: Int! +} + +type Recipient { + name: String! + email: String! +} + + +type SendEmailToFriendOutput { + sender: Sender + recipients: [Recipient] +} diff --git a/app/code/Magento/SendFriendGraphQl/registration.php b/app/code/Magento/SendFriendGraphQl/registration.php new file mode 100644 index 0000000000000..c41607a0dc864 --- /dev/null +++ b/app/code/Magento/SendFriendGraphQl/registration.php @@ -0,0 +1,9 @@ + Date: Mon, 5 Nov 2018 12:33:25 +0100 Subject: [PATCH 03/14] GraphQL-202: [Mutations] adds description and category_id as parameter --- app/code/Magento/SendFriendGraphQl/etc/schema.graphqls | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/SendFriendGraphQl/etc/schema.graphqls b/app/code/Magento/SendFriendGraphQl/etc/schema.graphqls index 87bf90fd10072..4123387650838 100644 --- a/app/code/Magento/SendFriendGraphQl/etc/schema.graphqls +++ b/app/code/Magento/SendFriendGraphQl/etc/schema.graphqls @@ -2,7 +2,7 @@ # See COPYING.txt for license details. type Mutation { - sendEmailToFriend (input: SendEmailToFriendSenderInput): SendEmailToFriendOutput @resolver(class: "\\Magento\\SendFriendGraphQl\\Model\\Resolver\\SendEmailToFriend") @doc(description:"@todo") + sendEmailToFriend (input: SendEmailToFriendSenderInput): SendEmailToFriendOutput @resolver(class: "\\Magento\\SendFriendGraphQl\\Model\\Resolver\\SendEmailToFriend") @doc(description:"Recommends Product by Sending Single/Multiple Email") } input SendEmailToFriendSenderInput { @@ -16,9 +16,9 @@ type Sender { email: String! message: String! } -#@todo Prams can be removed if dispatching of event in app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php not needed type Params { product_id: Int! + category_id: Int! } type Recipient { From 1fb624d381e67581a06e66809883e51a4a4b0d75 Mon Sep 17 00:00:00 2001 From: Tobias Maile Date: Mon, 5 Nov 2018 12:34:46 +0100 Subject: [PATCH 04/14] GraphQL-202: [Mutations] moves validation logic to separate module --- .../Model/Validation/Validation.php | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 app/code/Magento/SendFriendGraphQl/Model/Validation/Validation.php diff --git a/app/code/Magento/SendFriendGraphQl/Model/Validation/Validation.php b/app/code/Magento/SendFriendGraphQl/Model/Validation/Validation.php new file mode 100644 index 0000000000000..49f7feeaba489 --- /dev/null +++ b/app/code/Magento/SendFriendGraphQl/Model/Validation/Validation.php @@ -0,0 +1,69 @@ +sendFriend = $sendFriend; + $this->dataObjectFactory = $dataObjectFactory; + } + + /** + * @param $args + * @param array $recipientsArray + * @throws GraphQlInputException + */ + public function validate($args, array $recipientsArray): void + { + $this->prepareDataForSendFriendValidation($args, $recipientsArray); + $validationResult = $this->sendFriend->validate(); + if ($validationResult !== true) { + throw new GraphQlInputException(__(implode($validationResult))); + } + if ($this->sendFriend->getMaxSendsToFriend() && $this->sendFriend->isExceedLimit()) { + throw new GraphQlInputException(__('You can\'t send messages more than %1 times an hour.', + $this->sendFriend->getMaxSendsToFriend() + )); + } + } + + private function prepareDataForSendFriendValidation(array $args, array $recipientsArray): void + { + $sender = $this->dataObjectFactory->create()->setData([ + 'name' => $args['input']['sender']['name'], + 'email'=> $args['input']['sender']['email'], + 'message' => $args['input']['sender']['message'], + ]); + $emails = []; + foreach ($recipientsArray['recipients'] as $recipient) { + $emails[] = $recipient['email']; + } + $recipients = $this->dataObjectFactory->create()->setData('emails', $emails); + + $this->sendFriend->setData('_sender', $sender); + $this->sendFriend->setData('_recipients', $recipients); + } + +} \ No newline at end of file From f9acb655f01565c58d1df26643b4446407c4eb0a Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza Date: Thu, 8 Nov 2018 15:18:58 +0100 Subject: [PATCH 05/14] Added a separate resolver for returning category products count --- app/code/Magento/CatalogGraphQl/Model/Category/Hydrator.php | 1 - .../Magento/CatalogGraphQl/Model/Resolver/Category/Products.php | 2 +- app/code/Magento/CatalogGraphQl/etc/schema.graphqls | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/CatalogGraphQl/Model/Category/Hydrator.php b/app/code/Magento/CatalogGraphQl/Model/Category/Hydrator.php index f0cdab9498abb..e783c749fdc6e 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Category/Hydrator.php +++ b/app/code/Magento/CatalogGraphQl/Model/Category/Hydrator.php @@ -52,7 +52,6 @@ public function hydrateCategory(Category $category, $basicFieldsOnly = false) : $categoryData = $category->getData(); } else { $categoryData = $this->dataObjectProcessor->buildOutputDataArray($category, CategoryInterface::class); - $categoryData['product_count'] = $category->getProductCount(); } $categoryData['id'] = $category->getId(); $categoryData['children'] = []; diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Products.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Products.php index 557c7e08ff432..59c21b6b0109d 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Products.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Products.php @@ -65,7 +65,7 @@ public function resolve( 'eq' => $value['id'] ] ]; - $searchCriteria = $this->searchCriteriaBuilder->build($field->getName(), $args); + $searchCriteria = $this->searchCriteriaBuilder->build($field->getName(), $args); $searchCriteria->setCurrentPage($args['currentPage']); $searchCriteria->setPageSize($args['pageSize']); $searchResult = $this->filterQuery->getResult($searchCriteria, $info); diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index 5d62cb63f1662..7f31266ebf266 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -379,7 +379,7 @@ interface CategoryInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model level: Int @doc(description: "Indicates the depth of the category within the tree") created_at: String @doc(description: "Timestamp indicating when the category was created") updated_at: String @doc(description: "Timestamp indicating when the category was updated") - product_count: Int @doc(description: "The number of products in the category") + product_count: Int @doc(description: "The number of products in the category") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Category\\ProductsCount") default_sort_by: String @doc(description: "The attribute to use for sorting") products( pageSize: Int = 20 @doc(description: "Specifies the maximum number of results to return at once. This attribute is optional."), From 9aacf0e0f9044c133786de725fbe5d926c0223d5 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza Date: Thu, 8 Nov 2018 15:29:11 +0100 Subject: [PATCH 06/14] Missing resolver added --- .../Model/Resolver/Category/Products.php | 2 +- .../Model/Resolver/Category/ProductsCount.php | 70 +++++++++++++++++++ 2 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 app/code/Magento/CatalogGraphQl/Model/Resolver/Category/ProductsCount.php diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Products.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Products.php index 59c21b6b0109d..557c7e08ff432 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Products.php +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/Products.php @@ -65,7 +65,7 @@ public function resolve( 'eq' => $value['id'] ] ]; - $searchCriteria = $this->searchCriteriaBuilder->build($field->getName(), $args); + $searchCriteria = $this->searchCriteriaBuilder->build($field->getName(), $args); $searchCriteria->setCurrentPage($args['currentPage']); $searchCriteria->setPageSize($args['pageSize']); $searchResult = $this->filterQuery->getResult($searchCriteria, $info); diff --git a/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/ProductsCount.php b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/ProductsCount.php new file mode 100644 index 0000000000000..397fd12b7e714 --- /dev/null +++ b/app/code/Magento/CatalogGraphQl/Model/Resolver/Category/ProductsCount.php @@ -0,0 +1,70 @@ +catalogProductVisibility = $catalogProductVisibility; + $this->searchCriteria = $searchCriteria; + $this->stockProcessor = $stockProcessor; + } + + /** + * @inheritdoc + */ + public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) + { + if (!isset($value['model'])) { + throw new GraphQlInputException(__('"model" value should be specified')); + } + /** @var Category $category */ + $category = $value['model']; + $productsCollection = $category->getProductCollection(); + $productsCollection->setVisibility($this->catalogProductVisibility->getVisibleInSiteIds()); + $productsCollection = $this->stockProcessor->process($productsCollection, $this->searchCriteria, []); + + return $productsCollection->getSize(); + } +} From 19c1f871b6bb1853ad960edfc3f6c8372c8a3e4f Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza Date: Tue, 13 Nov 2018 11:40:06 +0100 Subject: [PATCH 07/14] API-functional tests coverage --- .../Catalog/CategoryProductsCountTest.php | 143 ++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryProductsCountTest.php diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryProductsCountTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryProductsCountTest.php new file mode 100644 index 0000000000000..eddd456a7b866 --- /dev/null +++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/CategoryProductsCountTest.php @@ -0,0 +1,143 @@ +productRepository = $objectManager->create(ProductRepositoryInterface::class); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php + */ + public function testCategoryWithSaleableProduct() + { + $categoryId = 2; + + $query = <<graphQlQuery($query); + + self::assertEquals(1, $response['category']['product_count']); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/category_product.php + */ + public function testCategoryWithInvisibleProduct() + { + $categoryId = 333; + $sku = 'simple333'; + + $product = $this->productRepository->get($sku); + $product->setVisibility(Visibility::VISIBILITY_NOT_VISIBLE); + $this->productRepository->save($product); + + $query = <<graphQlQuery($query); + + self::assertEquals(0, $response['category']['product_count']); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/product_simple_out_of_stock.php + */ + public function testCategoryWithOutOfStockProductManageStockEnabled() + { + $categoryId = 2; + + $query = <<graphQlQuery($query); + + self::assertEquals(0, $response['category']['product_count']); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/category_product.php + */ + public function testCategoryWithOutOfStockProductManageStockDisabled() + { + $categoryId = 333; + + $query = <<graphQlQuery($query); + + self::assertEquals(1, $response['category']['product_count']); + } + + /** + * @magentoApiDataFixture Magento/Catalog/_files/category_product.php + */ + public function testCategoryWithDisabledProduct() + { + $categoryId = 333; + $sku = 'simple333'; + + $product = $this->productRepository->get($sku); + $product->setStatus(ProductStatus::STATUS_DISABLED); + $this->productRepository->save($product); + + $query = <<graphQlQuery($query); + + self::assertEquals(0, $response['category']['product_count']); + } +} From faa85353df4be28674a07d406ff87e422284b985 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda Date: Mon, 19 Nov 2018 18:48:55 +0200 Subject: [PATCH 08/14] GraphQL-202: Products: Email to a Friend --- .../Model/Resolver/SendEmailToFriend.php | 179 +++++++++++------- .../Model/Validation/Validation.php | 69 ------- .../Magento/SendFriendGraphQl/composer.json | 26 +++ .../SendFriendGraphQl/etc/schema.graphqls | 9 +- composer.json | 1 + composer.lock | 2 +- 6 files changed, 145 insertions(+), 141 deletions(-) delete mode 100644 app/code/Magento/SendFriendGraphQl/Model/Validation/Validation.php create mode 100644 app/code/Magento/SendFriendGraphQl/composer.json diff --git a/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php b/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php index 56f6d20b20f18..06c5da94819df 100644 --- a/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php +++ b/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php @@ -7,38 +7,60 @@ namespace Magento\SendFriendGraphQl\Model\Resolver; +use Magento\Catalog\Api\Data\ProductInterface; use Magento\Catalog\Api\ProductRepositoryInterface; use Magento\Framework\DataObjectFactory; +use Magento\Framework\Event\ManagerInterface; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\GraphQl\Config\Element\Field; use Magento\Framework\GraphQl\Exception\GraphQlInputException; +use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; use Magento\Framework\GraphQl\Query\ResolverInterface; use Magento\Framework\GraphQl\Schema\Type\ResolveInfo; use Magento\SendFriend\Model\SendFriend; +use Magento\SendFriend\Model\SendFriendFactory; +/** + * @inheritdoc + */ class SendEmailToFriend implements ResolverInterface { /** - * @var SendFriend + * @var SendFriendFactory */ - private $sendFriend; + private $sendFriendFactory; + /** * @var ProductRepositoryInterface */ private $productRepository; + /** * @var DataObjectFactory */ private $dataObjectFactory; + /** + * @var ManagerInterface + */ + private $eventManager; + + /** + * @param SendFriendFactory $sendFriendFactory + * @param ProductRepositoryInterface $productRepository + * @param DataObjectFactory $dataObjectFactory + * @param ManagerInterface $eventManager + */ public function __construct( - SendFriend $sendFriend, + SendFriendFactory $sendFriendFactory, ProductRepositoryInterface $productRepository, - DataObjectFactory $dataObjectFactory + DataObjectFactory $dataObjectFactory, + ManagerInterface $eventManager ) { - $this->sendFriend = $sendFriend; + $this->sendFriendFactory = $sendFriendFactory; $this->productRepository = $productRepository; $this->dataObjectFactory = $dataObjectFactory; + $this->eventManager = $eventManager; } /** @@ -46,102 +68,131 @@ public function __construct( */ public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null) { - if ($this->sendFriend->getMaxSendsToFriend() && $this->sendFriend->isExceedLimit()) { + /** @var SendFriend $sendFriend */ + $sendFriend = $this->sendFriendFactory->create(); + + if ($sendFriend->getMaxSendsToFriend() && $sendFriend->isExceedLimit()) { throw new GraphQlInputException(__('You can\'t send messages more than %1 times an hour.', - $this->sendFriend->getMaxSendsToFriend() + $sendFriend->getMaxSendsToFriend() )); } - $product = $this->getProductFromRepository($args['input']['params']['product_id']); - $senderArray = $this->getSenderArrayFromArgs($args); - $recipientsArray = $this->getRecipientsArray($args); - //@todo clarify if event should be dispatched - //$this->_eventManager->dispatch('sendfriend_product', ['product' => $product]); - $this->sendFriend->setSender($senderArray); - $this->sendFriend->setRecipients($recipientsArray); - $this->sendFriend->setProduct($product); - - $this->prepareDataForValidation($args, $recipientsArray); - $validationResult = $this->sendFriend->validate(); - $this->addRecipientNameValidation($args); - if ($validationResult !== true) { - throw new GraphQlInputException(__(implode($validationResult))); - } + $product = $this->getProduct($args['input']['product_id']); + $this->eventManager->dispatch('sendfriend_product', ['product' => $product]); + $sendFriend->setProduct($product); - $this->sendFriend->send(); + $senderData = $this->extractSenderData($args); + $sendFriend->setSender($senderData); - return array_merge($senderArray, $recipientsArray); - } + $recipientsData = $this->extractRecipientsData($args); + $sendFriend->setRecipients($recipientsData); - private function prepareDataForValidation(array $args, array $recipientsArray): void - { - $sender = $this->dataObjectFactory->create()->setData([ - 'name' => $args['input']['sender']['name'], - 'email'=> $args['input']['sender']['email'], - 'message' => $args['input']['sender']['message'], - ]); - $emails = []; - foreach ($recipientsArray['recipients'] as $recipient) { - $emails[] = $recipient['email']; - } - $recipients = $this->dataObjectFactory->create()->setData('emails', $emails); + $this->validateSendFriendModel($sendFriend, $senderData, $recipientsData); + $sendFriend->send(); - $this->sendFriend->setData('_sender', $sender); - $this->sendFriend->setData('_recipients', $recipients); + return array_merge($senderData, $recipientsData); } /** - * @param array $args + * Validate send friend model + * + * @param SendFriend $sendFriend + * @param array $senderData + * @param array $recipientsData + * @return void * @throws GraphQlInputException */ - private function addRecipientNameValidation(array $args): void + private function validateSendFriendModel(SendFriend $sendFriend, array $senderData, array $recipientsData): void { - foreach ($args['input']['recipients'] as $recipient) { - if (empty($recipient['name'])) { - throw new GraphQlInputException( - __('Please Provide Name for Recipient with this Email Address: ' . $recipient['email'] - )); - } + $sender = $this->dataObjectFactory->create()->setData($senderData['sender']); + $sendFriend->setData('_sender', $sender); + + $emails = array_column($recipientsData['recipients'], 'email'); + $recipients = $this->dataObjectFactory->create()->setData('emails', $emails); + $sendFriend->setData('_recipients', $recipients); + + $validationResult = $sendFriend->validate(); + if ($validationResult !== true) { + throw new GraphQlInputException(__(implode($validationResult))); } } /** + * Get product + * * @param int $productId - * @return bool|\Magento\Catalog\Api\Data\ProductInterface + * @return ProductInterface + * @throws GraphQlNoSuchEntityException */ - private function getProductFromRepository(int $productId) + private function getProduct(int $productId): ProductInterface { try { $product = $this->productRepository->getById($productId); if (!$product->isVisibleInCatalog()) { - return false; + throw new GraphQlNoSuchEntityException( + __("The product that was requested doesn't exist. Verify the product and try again.") + ); } - } catch (NoSuchEntityException $noEntityException) { - return false; + } catch (NoSuchEntityException $e) { + throw new GraphQlNoSuchEntityException(__($e->getMessage()), $e); } - return $product; } - private function getRecipientsArray(array $args): array + /** + * Extract recipients data + * + * @param array $args + * @return array + * @throws GraphQlInputException + */ + private function extractRecipientsData(array $args): array { - $recipientsArray = []; + $recipients = []; foreach ($args['input']['recipients'] as $recipient) { - $recipientsArray[] = [ + if (empty($recipient['name'])) { + throw new GraphQlInputException(__('Please provide Name for all of recipients.')); + } + + if (empty($recipient['email'])) { + throw new GraphQlInputException(__('Please provide Email for all of recipients.')); + } + + $recipients[] = [ 'name' => $recipient['name'], 'email' => $recipient['email'], ]; } - return ['recipients' => $recipientsArray]; + return ['recipients' => $recipients]; } - private function getSenderArrayFromArgs(array $args): array + /** + * Extract sender data + * + * @param array $args + * @return array + * @throws GraphQlInputException + */ + private function extractSenderData(array $args): array { - return ['sender' => [ - 'name' => $args['input']['sender']['name'], - 'email' => $args['input']['sender']['email'], - 'message' => $args['input']['sender']['message'], - ] - ]; + if (empty($args['input']['sender']['name'])) { + throw new GraphQlInputException(__('Please provide Name of sender.')); + } + + if (empty($args['input']['sender']['email'])) { + throw new GraphQlInputException(__('Please provide Email of sender.')); + } + + if (empty($args['input']['sender']['message'])) { + throw new GraphQlInputException(__('Please provide Message.')); + } + + return [ + 'sender' => [ + 'name' => $args['input']['sender']['name'], + 'email' => $args['input']['sender']['email'], + 'message' => $args['input']['sender']['message'], + ], + ]; } } diff --git a/app/code/Magento/SendFriendGraphQl/Model/Validation/Validation.php b/app/code/Magento/SendFriendGraphQl/Model/Validation/Validation.php deleted file mode 100644 index 49f7feeaba489..0000000000000 --- a/app/code/Magento/SendFriendGraphQl/Model/Validation/Validation.php +++ /dev/null @@ -1,69 +0,0 @@ -sendFriend = $sendFriend; - $this->dataObjectFactory = $dataObjectFactory; - } - - /** - * @param $args - * @param array $recipientsArray - * @throws GraphQlInputException - */ - public function validate($args, array $recipientsArray): void - { - $this->prepareDataForSendFriendValidation($args, $recipientsArray); - $validationResult = $this->sendFriend->validate(); - if ($validationResult !== true) { - throw new GraphQlInputException(__(implode($validationResult))); - } - if ($this->sendFriend->getMaxSendsToFriend() && $this->sendFriend->isExceedLimit()) { - throw new GraphQlInputException(__('You can\'t send messages more than %1 times an hour.', - $this->sendFriend->getMaxSendsToFriend() - )); - } - } - - private function prepareDataForSendFriendValidation(array $args, array $recipientsArray): void - { - $sender = $this->dataObjectFactory->create()->setData([ - 'name' => $args['input']['sender']['name'], - 'email'=> $args['input']['sender']['email'], - 'message' => $args['input']['sender']['message'], - ]); - $emails = []; - foreach ($recipientsArray['recipients'] as $recipient) { - $emails[] = $recipient['email']; - } - $recipients = $this->dataObjectFactory->create()->setData('emails', $emails); - - $this->sendFriend->setData('_sender', $sender); - $this->sendFriend->setData('_recipients', $recipients); - } - -} \ No newline at end of file diff --git a/app/code/Magento/SendFriendGraphQl/composer.json b/app/code/Magento/SendFriendGraphQl/composer.json new file mode 100644 index 0000000000000..10d7e63bfc770 --- /dev/null +++ b/app/code/Magento/SendFriendGraphQl/composer.json @@ -0,0 +1,26 @@ +{ + "name": "magento/module-send-friend-graph-ql", + "description": "N/A", + "type": "magento2-module", + "require": { + "php": "~7.1.3||~7.2.0", + "magento/framework": "*", + "magento/module-catalog": "*", + "magento/module-send-friend": "*" + }, + "suggest": { + "magento/module-graph-ql": "*" + }, + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "autoload": { + "files": [ + "registration.php" + ], + "psr-4": { + "Magento\\SendFriendGraphGl\\": "" + } + } +} diff --git a/app/code/Magento/SendFriendGraphQl/etc/schema.graphqls b/app/code/Magento/SendFriendGraphQl/etc/schema.graphqls index 4123387650838..3915d48681ab1 100644 --- a/app/code/Magento/SendFriendGraphQl/etc/schema.graphqls +++ b/app/code/Magento/SendFriendGraphQl/etc/schema.graphqls @@ -6,9 +6,9 @@ type Mutation { } input SendEmailToFriendSenderInput { + product_id: Int! sender: Sender! - params: Params! - recipients: [Recipient] + recipients: [Recipient!]! } type Sender { @@ -16,17 +16,12 @@ type Sender { email: String! message: String! } -type Params { - product_id: Int! - category_id: Int! -} type Recipient { name: String! email: String! } - type SendEmailToFriendOutput { sender: Sender recipients: [Recipient] diff --git a/composer.json b/composer.json index 3f8f0a033c893..99f5beeb9c7e7 100644 --- a/composer.json +++ b/composer.json @@ -208,6 +208,7 @@ "magento/module-search": "*", "magento/module-security": "*", "magento/module-send-friend": "*", + "magento/module-send-friend-graph-ql": "*", "magento/module-shipping": "*", "magento/module-signifyd": "*", "magento/module-sitemap": "*", diff --git a/composer.lock b/composer.lock index 1d101c8aaaf15..a3e7a72e69026 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "d6640ddfd342feceaec44c406c056f57", + "content-hash": "886f5497f18a46a42d05cc672f1b8f2f", "packages": [ { "name": "braintree/braintree_php", From b6e07229fbd610a6617d47ab4c73cae0c335bb8f Mon Sep 17 00:00:00 2001 From: Valeriy Nayda Date: Mon, 19 Nov 2018 18:53:31 +0200 Subject: [PATCH 09/14] GraphQL-202: Products: Email to a Friend --- composer.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.lock b/composer.lock index 36b4dca023191..f26b71f1cc392 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "7538e15ea4ff1378cf55983ce9acba82", + "content-hash": "93418bd14ad2d9f54f4059550ded7061", "packages": [ { "name": "braintree/braintree_php", From a653c2baf540fa0a7c42f84a8d72e9228aaeb9d4 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda Date: Mon, 19 Nov 2018 20:18:31 +0200 Subject: [PATCH 10/14] GraphQL-202: Products: Email to a Friend --- app/code/Magento/SendFriendGraphQl/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 app/code/Magento/SendFriendGraphQl/README.md diff --git a/app/code/Magento/SendFriendGraphQl/README.md b/app/code/Magento/SendFriendGraphQl/README.md new file mode 100644 index 0000000000000..d8051922ddad7 --- /dev/null +++ b/app/code/Magento/SendFriendGraphQl/README.md @@ -0,0 +1,3 @@ +# SendFriendGraphQl + +**SendFriendGraphQl** provides support of GraphQL for SendFriend functionality. From 0bdc2fd3918e9fbd6ab48dc5cd97b270b17d163a Mon Sep 17 00:00:00 2001 From: Valeriy Nayda Date: Mon, 19 Nov 2018 20:35:53 +0200 Subject: [PATCH 11/14] GraphQL-202: Products: Email to a Friend -- fix static tests --- .../SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php | 3 ++- app/code/Magento/SendFriendGraphQl/registration.php | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php b/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php index 06c5da94819df..2b183ca209c0c 100644 --- a/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php +++ b/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php @@ -72,7 +72,8 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value $sendFriend = $this->sendFriendFactory->create(); if ($sendFriend->getMaxSendsToFriend() && $sendFriend->isExceedLimit()) { - throw new GraphQlInputException(__('You can\'t send messages more than %1 times an hour.', + throw new GraphQlInputException( + __('You can\'t send messages more than %1 times an hour.', $sendFriend->getMaxSendsToFriend() )); } diff --git a/app/code/Magento/SendFriendGraphQl/registration.php b/app/code/Magento/SendFriendGraphQl/registration.php index c41607a0dc864..5988738268147 100644 --- a/app/code/Magento/SendFriendGraphQl/registration.php +++ b/app/code/Magento/SendFriendGraphQl/registration.php @@ -3,6 +3,7 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); use Magento\Framework\Component\ComponentRegistrar; From b6d9adeed9bd275e0e819c33af35dff134b17834 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda Date: Mon, 19 Nov 2018 20:40:10 +0200 Subject: [PATCH 12/14] GraphQL-202: Products: Email to a Friend -- fix static tests --- app/code/Magento/SendFriendGraphQl/composer.json | 2 +- app/code/Magento/SendFriendGraphQl/etc/module.xml | 2 +- app/code/Magento/SendFriendGraphQl/registration.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/SendFriendGraphQl/composer.json b/app/code/Magento/SendFriendGraphQl/composer.json index 10d7e63bfc770..d401f57b2257a 100644 --- a/app/code/Magento/SendFriendGraphQl/composer.json +++ b/app/code/Magento/SendFriendGraphQl/composer.json @@ -20,7 +20,7 @@ "registration.php" ], "psr-4": { - "Magento\\SendFriendGraphGl\\": "" + "Magento\\SendFriendGraphQl\\": "" } } } diff --git a/app/code/Magento/SendFriendGraphQl/etc/module.xml b/app/code/Magento/SendFriendGraphQl/etc/module.xml index 14d792198cd5f..3df33266cac6e 100644 --- a/app/code/Magento/SendFriendGraphQl/etc/module.xml +++ b/app/code/Magento/SendFriendGraphQl/etc/module.xml @@ -7,5 +7,5 @@ --> - + diff --git a/app/code/Magento/SendFriendGraphQl/registration.php b/app/code/Magento/SendFriendGraphQl/registration.php index 5988738268147..13ec47b16abdb 100644 --- a/app/code/Magento/SendFriendGraphQl/registration.php +++ b/app/code/Magento/SendFriendGraphQl/registration.php @@ -7,4 +7,4 @@ use Magento\Framework\Component\ComponentRegistrar; -ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Magento_SendFriendGraphGl', __DIR__); +ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Magento_SendFriendGraphQl', __DIR__); From 05c1c8a02790974b5574f66a3ba81f721c325785 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda Date: Mon, 19 Nov 2018 21:00:42 +0200 Subject: [PATCH 13/14] GraphQL-202: Products: Email to a Friend -- fix static tests --- .../SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php b/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php index 2b183ca209c0c..c0c01c71df764 100644 --- a/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php +++ b/app/code/Magento/SendFriendGraphQl/Model/Resolver/SendEmailToFriend.php @@ -73,9 +73,8 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value if ($sendFriend->getMaxSendsToFriend() && $sendFriend->isExceedLimit()) { throw new GraphQlInputException( - __('You can\'t send messages more than %1 times an hour.', - $sendFriend->getMaxSendsToFriend() - )); + __('You can\'t send messages more than %1 times an hour.', $sendFriend->getMaxSendsToFriend()) + ); } $product = $this->getProduct($args['input']['product_id']); From 3694c65e95fa12258afdfc561ff29ad23fb00969 Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza Date: Tue, 20 Nov 2018 12:12:37 +0100 Subject: [PATCH 14/14] Added model to category data upon the hydration --- app/code/Magento/CatalogGraphQl/Model/Category/Hydrator.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/CatalogGraphQl/Model/Category/Hydrator.php b/app/code/Magento/CatalogGraphQl/Model/Category/Hydrator.php index e783c749fdc6e..d2c1fc8f7be9f 100644 --- a/app/code/Magento/CatalogGraphQl/Model/Category/Hydrator.php +++ b/app/code/Magento/CatalogGraphQl/Model/Category/Hydrator.php @@ -56,6 +56,7 @@ public function hydrateCategory(Category $category, $basicFieldsOnly = false) : $categoryData['id'] = $category->getId(); $categoryData['children'] = []; $categoryData['available_sort_by'] = $category->getAvailableSortBy(); + $categoryData['model'] = $category; return $this->flattener->flatten($categoryData); } }