vendor/pimcore/data-hub/src/GraphQL/FieldHelper/AbstractFieldHelper.php line 152

Open in your IDE?
  1. <?php
  2. /**
  3.  * Pimcore
  4.  *
  5.  * This source file is available under two different licenses:
  6.  * - GNU General Public License version 3 (GPLv3)
  7.  * - Pimcore Commercial License (PCL)
  8.  * Full copyright and license information is available in
  9.  * LICENSE.md which is distributed with this source code.
  10.  *
  11.  *  @copyright  Copyright (c) Pimcore GmbH (http://www.pimcore.org)
  12.  *  @license    http://www.pimcore.org/license     GPLv3 and PCL
  13.  */
  14. namespace Pimcore\Bundle\DataHubBundle\GraphQL\FieldHelper;
  15. use GraphQL\Language\AST\ArgumentNode;
  16. use GraphQL\Language\AST\FieldNode;
  17. use GraphQL\Language\AST\FragmentSpreadNode;
  18. use GraphQL\Language\AST\InlineFragmentNode;
  19. use GraphQL\Language\AST\NodeList;
  20. use GraphQL\Language\AST\SelectionSetNode;
  21. use GraphQL\Type\Definition\ResolveInfo;
  22. use Pimcore\Bundle\DataHubBundle\GraphQL\Traits\ServiceTrait;
  23. use Pimcore\Model\Element\ElementInterface;
  24. abstract class AbstractFieldHelper
  25. {
  26.     use ServiceTrait;
  27.     public function __construct()
  28.     {
  29.     }
  30.     /**
  31.      * @param object $container
  32.      * @param string $astName
  33.      *
  34.      * @return bool
  35.      */
  36.     public function skipField($container, $astName)
  37.     {
  38.         return false;
  39.     }
  40.     /**
  41.      * @param FieldNode $ast
  42.      * @param array $data
  43.      * @param object $container
  44.      * @param array $args
  45.      * @param array $context
  46.      * @param ResolveInfo|null $resolveInfo $resolveInfo
  47.      */
  48.     public function doExtractData(FieldNode $ast, &$data, $container, $args, $context, $resolveInfo = null)
  49.     {
  50.         $astName = $ast->name->value;
  51.         // sometimes we just want to expand relations just to throw them away afterwards because not requested
  52.         if ($this->skipField($container, $astName)) {
  53.             return;
  54.         }
  55.         // example for http://webonyx.github.io/graphql-php/error-handling/
  56. //         throw new MySafeException("fieldhelper", "TBD customized error message");
  57.         $getter = 'get' . ucfirst($astName);
  58.         $arguments = $this->getArguments($ast);
  59.         $languageArgument = isset($arguments['language']) ? $arguments['language'] : null;
  60.         if (method_exists($container, $getter)) {
  61.             if ($languageArgument) {
  62.                 if ($ast->alias) {
  63.                     // defer it
  64.                     $data[$astName] = function ($source, $args, $context, ResolveInfo $info) use (
  65.                         $container,
  66.                         $getter
  67.                     ) {
  68.                         return $container->$getter($args['language'] ?? null);
  69.                     };
  70.                 } else {
  71.                     $data[$astName] = $container->$getter($languageArgument);
  72.                 }
  73.             } else {
  74.                 $data[$astName] = $container->$getter();
  75.             }
  76.         }
  77.     }
  78.     /**
  79.      * @param FieldNode $ast
  80.      *
  81.      * @return array
  82.      */
  83.     public function getArguments(FieldNode $ast)
  84.     {
  85.         $result = [];
  86.         $nodeList = $ast->arguments;
  87.         $count = $nodeList->count();
  88.         for ($i = 0; $i < $count; $i++) {
  89.             /** @var ArgumentNode $argumentNode */
  90.             $argumentNode = $nodeList[$i];
  91.             $value = $argumentNode->value->kind === 'ListValue' ? $argumentNode->value->values : $argumentNode->value->value;
  92.             $result[$argumentNode->name->value] = $value;
  93.         }
  94.         return $result;
  95.     }
  96.     /**
  97.      * @param mixed $data
  98.      * @param object $container
  99.      * @param array $args
  100.      * @param array $context
  101.      * @param ResolveInfo|null $resolveInfo
  102.      *
  103.      * @return array
  104.      */
  105.     public function extractData(&$data, $container, $args, $context = [], ResolveInfo $resolveInfo = null)
  106.     {
  107.         if ($container instanceof ElementInterface) {
  108.             // we have to at least add the ID and pass it around even if not requested because we need it internally
  109.             // to resolve fields of linked elements (such as asset image and so on)
  110.             $data['id'] = $container->getId();
  111.         }
  112.         $resolveInfoArray = (array)$resolveInfo;
  113.         $fieldAstList = (array) $resolveInfoArray['fieldNodes'];
  114.         foreach ($fieldAstList as $astNode) {
  115.             if ($astNode instanceof FieldNode) {
  116.                 /** @var SelectionSetNode $selectionSet */
  117.                 $selectionSet = $astNode->selectionSet;
  118.                 if ($selectionSet !== null) {
  119.                     $selections = $selectionSet->selections;
  120.                     $this->processSelections($data, $selections, $container, $args, $context, $resolveInfo);
  121.                 }
  122.             }
  123.         }
  124.         return $data;
  125.     }
  126.     /**
  127.      * @param mixed $data
  128.      * @param NodeList|null $selections
  129.      * @param object $container
  130.      * @param array $args
  131.      * @param array $context
  132.      * @param ResolveInfo $resolveInfo
  133.      */
  134.     public function processSelections(&$data, $selections, $container, $args, $context, ResolveInfo $resolveInfo)
  135.     {
  136.         if (!$selections) {
  137.             return;
  138.         }
  139.         foreach ($selections as $selectionNode) {
  140.             if ($selectionNode instanceof FieldNode) {
  141.                 $this->doExtractData($selectionNode, $data, $container, $args, $context, $resolveInfo);
  142.             } elseif ($selectionNode instanceof InlineFragmentNode) {
  143.                 $inlineSelectionSetNode = $selectionNode->selectionSet;
  144.                 /** @var NodeList $inlineSelections */
  145.                 $inlineSelections = $inlineSelectionSetNode->selections;
  146.                 $count = $inlineSelections->count();
  147.                 for ($i = 0; $i < $count; $i++) {
  148.                     $inlineNode = $inlineSelections[$i];
  149.                     if ($inlineNode instanceof FieldNode) {
  150.                         $this->doExtractData($inlineNode, $data, $container, $args, $context, $resolveInfo);
  151.                     }
  152.                 }
  153.             } elseif ($selectionNode instanceof FragmentSpreadNode) {
  154.                 $fragmentName = $selectionNode->name->value;
  155.                 $knownFragments = $resolveInfo->fragments;
  156.                 $resolvedFragment = $knownFragments[$fragmentName];
  157.                 if ($resolvedFragment) {
  158.                     $fragmentSelectionSet = $resolvedFragment->selectionSet;
  159.                     $fragmentSelections = $fragmentSelectionSet->selections;
  160.                     $this->processSelections($data, $fragmentSelections, $container, $args, $context, $resolveInfo);
  161.                 }
  162.             }
  163.         }
  164.     }
  165. }