Skip to content

Commit

Permalink
Merge pull request #1623 from magento-honey-badgers/MAGETWO-81033-Gra…
Browse files Browse the repository at this point in the history
…ph-Ql-Get-Simple-Product

[honey] MAGETWO-81033: API for fetching single simple product
  • Loading branch information
cpartica authored Oct 25, 2017
2 parents acd713f + f24a929 commit fef1485
Show file tree
Hide file tree
Showing 39 changed files with 3,026 additions and 553 deletions.
77 changes: 77 additions & 0 deletions app/code/Magento/GraphQl/Controller/GraphQl.php
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 app/code/Magento/GraphQl/Model/Resolver/MediaGalleryEntries.php
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;
}
}
149 changes: 149 additions & 0 deletions app/code/Magento/GraphQl/Model/Resolver/Product.php
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;
}
}
Loading

0 comments on commit fef1485

Please sign in to comment.