forked from magento/graphql-ce
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1623 from magento-honey-badgers/MAGETWO-81033-Gra…
…ph-Ql-Get-Simple-Product [honey] MAGETWO-81033: API for fetching single simple product
- Loading branch information
Showing
39 changed files
with
3,026 additions
and
553 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
<?php | ||
/** | ||
* Copyright © Magento, Inc. All rights reserved. | ||
* See COPYING.txt for license details. | ||
*/ | ||
|
||
namespace Magento\GraphQl\Controller; | ||
|
||
use GraphQL\Error\FormattedError; | ||
use Magento\Framework\App\FrontControllerInterface; | ||
use Magento\Framework\App\RequestInterface; | ||
use Magento\Framework\App\ResponseInterface; | ||
use Magento\Framework\Webapi\Response; | ||
use Magento\GraphQl\Model\SchemaGeneratorInterface; | ||
|
||
/** | ||
* Front controller for web API GraphQL area. | ||
*/ | ||
class GraphQl implements FrontControllerInterface | ||
{ | ||
/** | ||
* @var Response | ||
*/ | ||
private $response; | ||
|
||
/** | ||
* @var SchemaGeneratorInterface | ||
*/ | ||
private $schemaGenerator; | ||
|
||
/** | ||
* Initialize dependencies | ||
* | ||
* @param Response $response | ||
* @param SchemaGeneratorInterface $schemaGenerator | ||
*/ | ||
public function __construct( | ||
Response $response, | ||
SchemaGeneratorInterface $schemaGenerator | ||
) { | ||
$this->response = $response; | ||
$this->schemaGenerator = $schemaGenerator; | ||
} | ||
|
||
/** | ||
* Handle GraphQL request | ||
* | ||
* @param RequestInterface $request | ||
* @return ResponseInterface | ||
*/ | ||
public function dispatch(RequestInterface $request) | ||
{ | ||
try { | ||
if ($request->getHeader('Content-Type') | ||
&& strpos($request->getHeader('Content-Type'), 'application/json') !== false | ||
) { | ||
$raw = file_get_contents('php://input') ?: ''; | ||
$data = json_decode($raw, true); | ||
} else { | ||
$data = $_REQUEST; | ||
} | ||
$schema = $this->schemaGenerator->generate(); | ||
$result = \GraphQL\GraphQL::execute( | ||
$schema, | ||
isset($data['query']) ? $data['query'] : '', | ||
null, | ||
null, | ||
isset($data['variables']) ? $data['variables'] : [] | ||
); | ||
} catch (\Exception $error) { | ||
$result['extensions']['exception'] = FormattedError::createFromException($error); | ||
$this->response->setStatusCode(500); | ||
} | ||
$this->response->setBody(json_encode($result))->setHeader('Content-Type', 'application/json'); | ||
return $this->response; | ||
} | ||
} |
77 changes: 77 additions & 0 deletions
77
app/code/Magento/GraphQl/Model/Resolver/MediaGalleryEntries.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
<?php | ||
/** | ||
* Copyright © Magento, Inc. All rights reserved. | ||
* See COPYING.txt for license details. | ||
*/ | ||
|
||
namespace Magento\GraphQl\Model\Resolver; | ||
|
||
use Magento\Catalog\Api\ProductAttributeMediaGalleryManagementInterface; | ||
use Magento\Framework\Api\ExtensibleDataInterface; | ||
use Magento\Framework\Exception\NoSuchEntityException; | ||
use Magento\Framework\Webapi\ServiceOutputProcessor; | ||
|
||
/** | ||
* Media gallery field resolver, used for GraphQL request processing. | ||
*/ | ||
class MediaGalleryEntries | ||
{ | ||
/** | ||
* @var ProductAttributeMediaGalleryManagementInterface | ||
*/ | ||
private $mediaGalleryManagement; | ||
|
||
/** | ||
* @var ServiceOutputProcessor | ||
*/ | ||
private $serviceOutputProcessor; | ||
|
||
/** | ||
* MediaGalleryEntries constructor. | ||
* | ||
* @param ProductAttributeMediaGalleryManagementInterface $mediaGalleryManagement | ||
* @param ServiceOutputProcessor $serviceOutputProcessor | ||
*/ | ||
public function __construct( | ||
ProductAttributeMediaGalleryManagementInterface $mediaGalleryManagement, | ||
ServiceOutputProcessor $serviceOutputProcessor | ||
) { | ||
$this->mediaGalleryManagement = $mediaGalleryManagement; | ||
$this->serviceOutputProcessor = $serviceOutputProcessor; | ||
} | ||
|
||
/** | ||
* Get media gallery entries for the specified product. | ||
* | ||
* @param string $sku | ||
* @return array|null | ||
*/ | ||
public function getMediaGalleryEntries(string $sku) | ||
{ | ||
try { | ||
$mediaGalleryObjectArray = $this->mediaGalleryManagement->getList($sku); | ||
} catch (NoSuchEntityException $e) { | ||
// No error should be thrown, null result should be returned | ||
return null; | ||
} | ||
|
||
$mediaGalleryList = $this->serviceOutputProcessor->process( | ||
$mediaGalleryObjectArray, | ||
ProductAttributeMediaGalleryManagementInterface::class, | ||
'getList' | ||
); | ||
|
||
foreach ($mediaGalleryList as $key => $mediaGallery) { | ||
if (isset($mediaGallery[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]) | ||
&& isset($mediaGallery[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]['video_content'])) { | ||
$mediaGallery = array_merge( | ||
$mediaGallery, | ||
$mediaGallery[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY] | ||
); | ||
$mediaGalleryList[$key] = $mediaGallery; | ||
} | ||
} | ||
|
||
return $mediaGalleryList; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
<?php | ||
/** | ||
* Copyright © Magento, Inc. All rights reserved. | ||
* See COPYING.txt for license details. | ||
*/ | ||
|
||
namespace Magento\GraphQl\Model\Resolver; | ||
|
||
use Magento\Catalog\Api\ProductRepositoryInterface; | ||
use Magento\Framework\Exception\NoSuchEntityException; | ||
use Magento\Framework\Webapi\ServiceOutputProcessor; | ||
|
||
/** | ||
* Product field resolver, used for GraphQL request processing. | ||
*/ | ||
class Product | ||
{ | ||
/** | ||
* @var ProductRepositoryInterface | ||
*/ | ||
private $productRepository; | ||
|
||
/** | ||
* @var ServiceOutputProcessor | ||
*/ | ||
private $serviceOutputProcessor; | ||
|
||
/** | ||
* @var MediaGalleryEntries | ||
*/ | ||
private $mediaGalleryResolver; | ||
|
||
/** | ||
* Initialize dependencies | ||
* | ||
* @param ProductRepositoryInterface $productRepository | ||
* @param ServiceOutputProcessor $serviceOutputProcessor | ||
* @param MediaGalleryEntries $mediaGalleryResolver | ||
*/ | ||
public function __construct( | ||
ProductRepositoryInterface $productRepository, | ||
ServiceOutputProcessor $serviceOutputProcessor, | ||
MediaGalleryEntries $mediaGalleryResolver | ||
) { | ||
$this->productRepository = $productRepository; | ||
$this->serviceOutputProcessor = $serviceOutputProcessor; | ||
$this->mediaGalleryResolver = $mediaGalleryResolver; | ||
} | ||
|
||
/** | ||
* Resolves product by Sku | ||
* | ||
* @param string $sku | ||
* @return array|null | ||
*/ | ||
public function getProduct(string $sku) | ||
{ | ||
try { | ||
$productObject = $this->productRepository->get($sku); | ||
} catch (NoSuchEntityException $e) { | ||
// No error should be thrown, null result should be returned | ||
return null; | ||
} | ||
return $this->processProduct($productObject); | ||
} | ||
|
||
/** | ||
* Resolves product by Id | ||
* | ||
* @param int $productId | ||
* @return array|null | ||
*/ | ||
public function getProductById(int $productId) | ||
{ | ||
try { | ||
$productObject = $this->productRepository->getById($productId); | ||
} catch (NoSuchEntityException $e) { | ||
// No error should be thrown, null result should be returned | ||
return null; | ||
} | ||
return $this->processProduct($productObject); | ||
} | ||
|
||
/** | ||
* Retrieve single product data in array format | ||
* | ||
* @param \Magento\Catalog\Api\Data\ProductInterface $productObject | ||
* @return array|null | ||
*/ | ||
private function processProduct(\Magento\Catalog\Api\Data\ProductInterface $productObject) | ||
{ | ||
$product = $this->serviceOutputProcessor->process( | ||
$productObject, | ||
ProductRepositoryInterface::class, | ||
'get' | ||
); | ||
$product = array_merge($product, $product['extension_attributes']); | ||
if (isset($product['custom_attributes'])) { | ||
$customAttributes = []; | ||
foreach ($product['custom_attributes'] as $attribute) { | ||
$isArray = false; | ||
if (is_array($attribute['value'])) { | ||
$isArray = true; | ||
foreach ($attribute['value'] as $attributeValue) { | ||
if (is_array($attributeValue)) { | ||
$customAttributes[$attribute['attribute_code']] = json_encode($attribute['value']); | ||
continue; | ||
} | ||
$customAttributes[$attribute['attribute_code']] = implode(',', $attribute['value']); | ||
continue; | ||
} | ||
} | ||
if ($isArray) { | ||
continue; | ||
} | ||
$customAttributes[$attribute['attribute_code']] = $attribute['value']; | ||
} | ||
} | ||
$product = array_merge($product, $customAttributes); | ||
$product = array_merge($product, $product['product_links']); | ||
$product['media_gallery_entries'] = $this | ||
->mediaGalleryResolver->getMediaGalleryEntries($productObject->getSku()); | ||
|
||
if (isset($product['configurable_product_links'])) { | ||
$product['configurable_product_links'] = $this | ||
->resolveConfigurableProductLinks($product['configurable_product_links']); | ||
} | ||
|
||
return $product; | ||
} | ||
|
||
/** | ||
* Resolve links for configurable product into simple products | ||
* | ||
* @param int[] | ||
* @return array | ||
*/ | ||
private function resolveConfigurableProductLinks($configurableProductLinks) | ||
{ | ||
if (empty($configurableProductLinks)) { | ||
return []; | ||
} | ||
$result = []; | ||
foreach ($configurableProductLinks as $key => $id) { | ||
$result[$key] = $this->getProductById($id); | ||
} | ||
return $result; | ||
} | ||
} |
Oops, something went wrong.