vendor/pimcore/data-hub/src/GraphQL/Service.php line 432

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. declare(strict_types=1);
  15. /**
  16.  * Pimcore
  17.  *
  18.  * This source file is available under two different licenses:
  19.  * - GNU General Public License version 3 (GPLv3)
  20.  * - Pimcore Commercial License (PCL)
  21.  * Full copyright and license information is available in
  22.  * LICENSE.md which is distributed with this source code.
  23.  *
  24.  *  @copyright  Copyright (c) Pimcore GmbH (http://www.pimcore.org)
  25.  *  @license    http://www.pimcore.org/license     GPLv3 and PCL
  26.  */
  27. namespace Pimcore\Bundle\DataHubBundle\GraphQL;
  28. use GraphQL\Type\Definition\ResolveInfo;
  29. use Pimcore\Bundle\DataHubBundle\Configuration;
  30. use Pimcore\Bundle\DataHubBundle\GraphQL\Exception\ClientSafeException;
  31. use Pimcore\Bundle\DataHubBundle\GraphQL\FieldHelper\AssetFieldHelper;
  32. use Pimcore\Bundle\DataHubBundle\GraphQL\FieldHelper\DataObjectFieldHelper;
  33. use Pimcore\Bundle\DataHubBundle\GraphQL\FieldHelper\DocumentFieldHelper;
  34. use Pimcore\Bundle\DataHubBundle\GraphQL\Query\Operator\Factory\OperatorFactoryInterface;
  35. use Pimcore\Bundle\DataHubBundle\GraphQL\Query\Value\DefaultValue;
  36. use Pimcore\Bundle\DataHubBundle\PimcoreDataHubBundle;
  37. use Pimcore\Cache\RuntimeCache;
  38. use Pimcore\DataObject\GridColumnConfig\ConfigElementInterface;
  39. use Pimcore\Localization\LocaleServiceInterface;
  40. use Pimcore\Model\Asset;
  41. use Pimcore\Model\DataObject\AbstractObject;
  42. use Pimcore\Model\DataObject\ClassDefinition;
  43. use Pimcore\Model\DataObject\ClassDefinition\Data;
  44. use Pimcore\Model\DataObject\Concrete;
  45. use Pimcore\Model\DataObject\Objectbrick\Data\AbstractData;
  46. use Pimcore\Model\DataObject\Objectbrick\Definition;
  47. use Pimcore\Model\Document;
  48. use Pimcore\Model\Element\ElementInterface;
  49. use Pimcore\Model\Factory;
  50. use Pimcore\Translation\Translator;
  51. use Psr\Container\ContainerInterface;
  52. class Service
  53. {
  54.     /***
  55.      * @var ContainerInterface
  56.      */
  57.     protected $dataObjectQueryTypeGeneratorFactories;
  58.     /***
  59.      * @var ContainerInterface
  60.      */
  61.     protected $dataObjectMutationTypeGeneratorFactories;
  62.     /**
  63.      * @var ContainerInterface
  64.      */
  65.     protected $dataObjectQueryOperatorFactories;
  66.     /**
  67.      * @var ContainerInterface
  68.      */
  69.     protected $documentElementQueryTypeGeneratorFactories;
  70.     /**
  71.      * @var ContainerInterface
  72.      */
  73.     protected $documentElementMutationGeneratorFactories;
  74.     /**
  75.      * @var ContainerInterface
  76.      */
  77.     protected $documentElementMutationTypeGeneratorFactories;
  78.     /**
  79.      * @var ContainerInterface
  80.      */
  81.     protected $dataObjectMutationOperatorFactories;
  82.     /**
  83.      * @var ContainerInterface
  84.      */
  85.     protected $generalTypeGeneratorFactories;
  86.     /**
  87.      * @var ContainerInterface
  88.      */
  89.     protected $assetTypeGeneratorFactories;
  90.     /**
  91.      * @var ContainerInterface
  92.      */
  93.     protected $csFeatureTypeGeneratorFactories;
  94.     protected ContainerInterface $translationTypeGeneratorFactories;
  95.     /**
  96.      * @var array
  97.      */
  98.     protected $supportedDataObjectQueryDataTypes;
  99.     /**
  100.      * @var array
  101.      */
  102.     protected $supportedDocumentElementQueryDataTypes;
  103.     /**
  104.      * @var array
  105.      */
  106.     protected $supportedDocumentElementMutationDataTypes;
  107.     /**
  108.      * @var array
  109.      */
  110.     protected $supportedCsFeatureQueryDataTypes;
  111.     /**
  112.      * @var array
  113.      */
  114.     protected $supportedDataObjectMutationDataTypes;
  115.     /**
  116.      * @var DataObjectFieldHelper
  117.      */
  118.     protected $objectFieldHelper;
  119.     /**
  120.      * @var AssetFieldHelper
  121.      */
  122.     protected $assetFieldHelper;
  123.     /**
  124.      * @var documentFieldHelper
  125.      */
  126.     protected $documentFieldHelper;
  127.     /**
  128.      * @var LocaleServiceInterface
  129.      */
  130.     protected $localeService;
  131.     /**
  132.      * @var Translator
  133.      */
  134.     protected $translator;
  135.     /**
  136.      * @var Factory
  137.      */
  138.     protected $modelFactory;
  139.     /**
  140.      * @var array
  141.      */
  142.     protected $generalTypes = [];
  143.     /**
  144.      * @var array
  145.      */
  146.     protected $assetDataTypes = [];
  147.     protected array $translationDataTypes = [];
  148.     /**
  149.      * @var array
  150.      */
  151.     protected $documentDataTypes = [];
  152.     /**
  153.      * @var array
  154.      */
  155.     protected $propertyDataTypes = [];
  156.     /**
  157.      * @var array
  158.      */
  159.     protected $classificationStoreDataTypes = [];
  160.     /**
  161.      * @var array
  162.      */
  163.     protected $dataObjectDataTypes = [];
  164.     public function __construct(
  165.         AssetFieldHelper $assetFieldHelper,
  166.         DocumentFieldHelper $documentFieldHelper,
  167.         DataObjectFieldHelper $objectFieldHelper,
  168.         LocaleServiceInterface $localeService,
  169.         Factory $modelFactory,
  170.         Translator $translator,
  171.         ContainerInterface $dataObjectQueryTypeGeneratorFactories,
  172.         ContainerInterface $dataObjectQueryOperatorFactories,
  173.         ContainerInterface $dataObjectMutationTypeGeneratorFactories,
  174.         ContainerInterface $dataObjectMutationOperatorFactories,
  175.         ContainerInterface $documentElementQueryTypeGeneratorFactories,
  176.         ContainerInterface $documentElementMutationTypeGeneratorFactories,
  177.         ContainerInterface $generalTypeGeneratorFactories,
  178.         ContainerInterface $assetTypeGeneratorFactories,
  179.         ContainerInterface $csFeatureTypeGeneratorFactories,
  180.         ContainerInterface $translationTypeGeneratorFactories
  181.     ) {
  182.         $this->assetFieldHelper $assetFieldHelper;
  183.         $this->documentFieldHelper $documentFieldHelper;
  184.         $this->objectFieldHelper $objectFieldHelper;
  185.         $this->localeService $localeService;
  186.         $this->modelFactory $modelFactory;
  187.         $this->translator $translator;
  188.         $this->dataObjectQueryTypeGeneratorFactories $dataObjectQueryTypeGeneratorFactories;
  189.         $this->dataObjectQueryOperatorFactories $dataObjectQueryOperatorFactories;
  190.         $this->dataObjectMutationTypeGeneratorFactories $dataObjectMutationTypeGeneratorFactories;
  191.         $this->dataObjectMutationOperatorFactories $dataObjectMutationOperatorFactories;
  192.         $this->documentElementQueryTypeGeneratorFactories $documentElementQueryTypeGeneratorFactories//TODO rename this to query
  193.         $this->documentElementMutationGeneratorFactories $documentElementMutationTypeGeneratorFactories;
  194.         $this->generalTypeGeneratorFactories $generalTypeGeneratorFactories;
  195.         $this->assetTypeGeneratorFactories $assetTypeGeneratorFactories;
  196.         $this->csFeatureTypeGeneratorFactories $csFeatureTypeGeneratorFactories;
  197.         $this->translationTypeGeneratorFactories $translationTypeGeneratorFactories;
  198.     }
  199.     /**
  200.      * @param string $attribute
  201.      * @param string $typeName
  202.      * @param Data|null $fieldDefinition
  203.      * @param ClassDefinition|\Pimcore\Model\DataObject\Fieldcollection\Definition|null $class
  204.      * @param object|null $container
  205.      *
  206.      * @return mixed
  207.      */
  208.     public function buildDataObjectQueryDataConfig($attribute$typeName$fieldDefinition null$class null$container null)
  209.     {
  210.         /** @var DataObjectQueryFieldConfigGeneratorInterface $factory */
  211.         $factory $this->dataObjectQueryTypeGeneratorFactories->get('typegenerator_dataobjectquerydatatype_' $typeName);
  212.         $result $factory->getGraphQlFieldConfig($attribute$fieldDefinition$class$container);
  213.         return $result;
  214.     }
  215.     /**
  216.      * @param array $nodeDef
  217.      * @param ClassDefinition|\Pimcore\Model\DataObject\Fieldcollection\Definition $class
  218.      * @param object|null $container
  219.      *
  220.      * @return array
  221.      */
  222.     public function buildDataObjectMutationDataConfig($nodeDef$class null$container null)
  223.     {
  224.         $typeName $nodeDef['attributes']['dataType'];
  225.         /** @var DataObjectMutationFieldConfigGeneratorInterface $factory */
  226.         $factory $this->dataObjectMutationTypeGeneratorFactories->get('typegenerator_dataobjectmutationdatatype_' $typeName);
  227.         $result $factory->getGraphQlMutationFieldConfig($nodeDef$class$container);
  228.         return $result;
  229.     }
  230.     /**
  231.      * @param string $attribute
  232.      * @param Data|null $fieldDefinition
  233.      * @param ClassDefinition|null $class
  234.      *
  235.      * @return callable(mixed $value, array $args, array $context, \GraphQL\Type\Definition\ResolveInfo $info): mixed
  236.      */
  237.     public function buildDataObjectDataQueryResolver($attributeData $fieldDefinition nullClassDefinition $class null)
  238.     {
  239.         $name $fieldDefinition->getFieldtype();
  240.         /** @var DataObjectQueryFieldConfigGeneratorInterface $factory */
  241.         $factory $this->dataObjectQueryTypeGeneratorFactories->get('typegenerator_dataobjectquerydatatype_' $name);
  242.         $resolver $factory->getResolver($attribute$fieldDefinition$class);
  243.         return $resolver;
  244.     }
  245.     /**
  246.      * @param Data|null $fieldDefinition
  247.      * @param ClassDefinition|null $class
  248.      * @param object|null $container
  249.      *
  250.      * @return mixed
  251.      */
  252.     public function buildDataObjectDataQueryType(Data $fieldDefinition nullClassDefinition $class null$container null)
  253.     {
  254.         $name $fieldDefinition->getFieldtype();
  255.         /** @var DataObjectQueryFieldConfigGeneratorInterface $factory */
  256.         $factory $this->dataObjectQueryTypeGeneratorFactories->get('typegenerator_dataobjectquerydatatype_' $name);
  257.         $result $factory->getFieldType($fieldDefinition$class$container);
  258.         return $result;
  259.     }
  260.     /**
  261.      * @param string $elementName
  262.      *
  263.      * @return mixed
  264.      */
  265.     public function buildDocumentElementDataQueryType($elementName)
  266.     {
  267.         $factory $this->documentElementQueryTypeGeneratorFactories->get('typegenerator_documentelementquerydatatype_' $elementName);
  268.         $result $factory->getFieldType();
  269.         return $result;
  270.     }
  271.     /**
  272.      * @param string $elementName
  273.      *
  274.      * @return mixed
  275.      */
  276.     public function buildDocumentElementDataMutationType($elementName)
  277.     {
  278.         $factory $this->documentElementMutationGeneratorFactories->get('typegenerator_documentelementmutationdatatype_' $elementName);
  279.         $result $factory->getDocumentElementMutationFieldConfig();
  280.         return $result;
  281.     }
  282.     /**
  283.      * @param string $elementName
  284.      *
  285.      * @return mixed
  286.      */
  287.     public function buildCsFeatureDataQueryType($elementName)
  288.     {
  289.         $factory $this->csFeatureTypeGeneratorFactories->get('typegenerator_csfeaturequerydatatype_' $elementName);
  290.         $result $factory->getFieldType();
  291.         return $result;
  292.     }
  293.     /**
  294.      * @param string $typeName
  295.      *
  296.      * @return bool
  297.      */
  298.     public function supportsDataObjectQueryDataType($typeName)
  299.     {
  300.         return $this->dataObjectQueryTypeGeneratorFactories->has('typegenerator_dataobjectquerydatatype_' $typeName);
  301.     }
  302.     /**
  303.      * @param string $typeName
  304.      *
  305.      * @return bool
  306.      */
  307.     public function supportsDataObjectMutationDataType($typeName)
  308.     {
  309.         return $this->dataObjectMutationTypeGeneratorFactories->has('typegenerator_dataobjectmutationdatatype_' $typeName);
  310.     }
  311.     /**
  312.      * @param string $typeName
  313.      * @param array $nodeDef
  314.      * @param ClassDefinition|null $class
  315.      * @param object|null $container
  316.      * @param array $params
  317.      *
  318.      * @return mixed
  319.      */
  320.     public function buildDataObjectQueryOperatorConfig($typeName$nodeDefClassDefinition $class null$container null$params = [])
  321.     {
  322.         $typeName strtolower($typeName);
  323.         /** @var DataObjectQueryFieldConfigGeneratorInterface $factory */
  324.         $factory $this->dataObjectQueryTypeGeneratorFactories->get('typegenerator_queryoperator_' $typeName);
  325.         $result $factory->getGraphQlQueryOperatorConfig($typeName$nodeDef$class$container$params);
  326.         return $result;
  327.     }
  328.     /**
  329.      * @param string $typeName
  330.      * @param array $nodeDef
  331.      * @param ClassDefinition|null $class
  332.      * @param object|null $container
  333.      * @param array $params
  334.      *
  335.      * @return mixed
  336.      *
  337.      * @throws \Exception
  338.      */
  339.     public function buildDataObjectMutationOperatorConfig($typeName$nodeDefClassDefinition $class null$container null$params = [])
  340.     {
  341.         $typeName strtolower($typeName);
  342.         // $factory = $this->mutationTypeGeneratorFactories->get('typegenerator_mutationoperator_' . $typeName);
  343.         $factory $this->dataObjectMutationOperatorFactories->get($typeName);
  344.         $context RuntimeCache::get(PimcoreDataHubBundle::RUNTIME_CONTEXT_KEY);
  345.         $configGenerator $factory->build($nodeDef['attributes'], $context);
  346.         $result $configGenerator->getGraphQlMutationOperatorConfig($nodeDef$class$container$params);
  347.         return $result;
  348.     }
  349.     /**
  350.      * @param string $mode
  351.      * @param string $typeName
  352.      * @param array $nodeDef
  353.      * @param ClassDefinition|null $class
  354.      * @param object|null $container
  355.      * @param array $params
  356.      *
  357.      * @return mixed
  358.      */
  359.     public function buildDataObjectOperatorQueryType($mode$typeName$nodeDefClassDefinition $class null$container null$params = [])
  360.     {
  361.         $typeName strtolower($typeName);
  362.         /** @var DataObjectQueryFieldConfigGeneratorInterface $factory */
  363.         $factory $this->dataObjectQueryTypeGeneratorFactories->get('typegenerator_operator_' $typeName);
  364.         $result $factory->getGraphQlOperatorConfig($mode$typeName$nodeDef$class$container$params);
  365.         return $result;
  366.     }
  367.     /**
  368.      * @param string $typeName
  369.      *
  370.      * @return mixed
  371.      *
  372.      * @throws \Exception
  373.      */
  374.     public function buildGeneralType($typeName)
  375.     {
  376.         $factory $this->generalTypeGeneratorFactories->get($typeName);
  377.         $result $factory->build();
  378.         return $result;
  379.     }
  380.     /**
  381.      * @param string $typeName
  382.      *
  383.      * @return mixed
  384.      *
  385.      * @throws \Exception
  386.      */
  387.     public function buildAssetType($typeName)
  388.     {
  389.         $factory $this->assetTypeGeneratorFactories->get($typeName);
  390.         $result $factory->build();
  391.         return $result;
  392.     }
  393.     /**
  394.      * @throws \Exception
  395.      */
  396.     public function buildTranslationType(string $typeName): mixed
  397.     {
  398.         $factory $this->translationTypeGeneratorFactories->get($typeName);
  399.         $result $factory->build();
  400.         return $result;
  401.     }
  402.     /**
  403.      * @param string $typeName
  404.      * @param array|null $attributes
  405.      * @param ClassDefinition|null $class
  406.      * @param object|null $container
  407.      *
  408.      * @return Query\Operator\OperatorInterface
  409.      */
  410.     public function buildQueryOperator($typeName$attributes nullClassDefinition $class null$container null)
  411.     {
  412.         $typeName strtolower($typeName);
  413.         /** @var OperatorFactoryInterface $factory */
  414.         $factory $this->dataObjectQueryOperatorFactories->get($typeName);
  415.         $context RuntimeCache::get(PimcoreDataHubBundle::RUNTIME_CONTEXT_KEY);
  416.         $result $factory->build($attributes$context);
  417.         return $result;
  418.     }
  419.     /**
  420.      * @param ConfigElementInterface $nodeConfig
  421.      *
  422.      * @return DefaultValue|Query\Operator\OperatorInterface
  423.      *
  424.      * @throws \Exception
  425.      */
  426.     public function buildValueResolverFromAttributes($nodeConfig)
  427.     {
  428.         $attributes $nodeConfig['attributes'];
  429.         if ($nodeConfig['isOperator']) {
  430.             $class $attributes['class'];
  431.             $operatorImpl $this->buildQueryOperator($class$attributes);
  432.             return $operatorImpl;
  433.         } else {
  434.             $context RuntimeCache::get(PimcoreDataHubBundle::RUNTIME_CONTEXT_KEY);
  435.             $operatorImpl = new DefaultValue($attributes$context);
  436.             $operatorImpl->setGraphQlService($this);
  437.             return $operatorImpl;
  438.         }
  439.     }
  440.     /**
  441.      * @return array
  442.      */
  443.     public function getSupportedDataObjectQueryDataTypes()
  444.     {
  445.         return $this->supportedDataObjectQueryDataTypes;
  446.     }
  447.     /**
  448.      * @param array $supportedDocumentElementQueryDataTypes
  449.      */
  450.     public function setSupportedDocumentElementQueryDataTypes($supportedDocumentElementQueryDataTypes)
  451.     {
  452.         $this->supportedDocumentElementQueryDataTypes $supportedDocumentElementQueryDataTypes;
  453.     }
  454.     /**
  455.      * @param array $supportedDocumentElementMutationDataTypes
  456.      */
  457.     public function setSupportedDocumentElementMutationDataTypes($supportedDocumentElementMutationDataTypes)
  458.     {
  459.         $this->supportedDocumentElementMutationDataTypes $supportedDocumentElementMutationDataTypes;
  460.     }
  461.     /**
  462.      * @param array $supportedCsFeatureQueryDataTypes
  463.      */
  464.     public function setSupportedCsFeatureQueryDataTypes($supportedCsFeatureQueryDataTypes)
  465.     {
  466.         $this->supportedCsFeatureQueryDataTypes $supportedCsFeatureQueryDataTypes;
  467.     }
  468.     /**
  469.      * @param array $generalTypes
  470.      */
  471.     public function setSupportedGeneralTypes($generalTypes)
  472.     {
  473.         $this->generalTypes $generalTypes;
  474.     }
  475.     /**
  476.      * @return array
  477.      */
  478.     public function getSupportedDocumentElementQueryDataTypes()
  479.     {
  480.         return $this->supportedDocumentElementQueryDataTypes;
  481.     }
  482.     /**
  483.      * @return array
  484.      */
  485.     public function getSupportedDocumentElementMutationDataTypes()
  486.     {
  487.         return $this->supportedDocumentElementMutationDataTypes;
  488.     }
  489.     /**
  490.      * @return array
  491.      */
  492.     public function getSupportedCsFeatureQueryDataTypes()
  493.     {
  494.         return $this->supportedCsFeatureQueryDataTypes;
  495.     }
  496.     /**
  497.      * @param array $supportedDataObjectQueryDataTypes
  498.      */
  499.     public function setSupportedDataObjectQueryDataTypes($supportedDataObjectQueryDataTypes)
  500.     {
  501.         $this->supportedDataObjectQueryDataTypes $supportedDataObjectQueryDataTypes;
  502.     }
  503.     public function getSupportedDataObjectMutationDataTypes(): array
  504.     {
  505.         return $this->supportedDataObjectMutationDataTypes;
  506.     }
  507.     public function setSupportedDataObjectMutationDataTypes(array $supportedDataObjectMutationDataTypes): void
  508.     {
  509.         $this->supportedDataObjectMutationDataTypes $supportedDataObjectMutationDataTypes;
  510.     }
  511.     /**
  512.      * @param mixed $value
  513.      *
  514.      * @return mixed
  515.      */
  516.     public function getElementFromArrayObject($value)
  517.     {
  518.         if ($value instanceof \ArrayObject) {
  519.             $value $value->getArrayCopy();
  520.             if (isset($value['__elementType'])) {
  521.                 $value \Pimcore\Model\Element\Service::getElementById($value['__elementType'], $value['id']);
  522.             }
  523.         }
  524.         return $value;
  525.     }
  526.     /**
  527.      * @return AssetFieldHelper
  528.      */
  529.     public function getAssetFieldHelper()
  530.     {
  531.         return $this->assetFieldHelper;
  532.     }
  533.     /**
  534.      * @return DocumentFieldHelper
  535.      */
  536.     public function getDocumentFieldHelper()
  537.     {
  538.         return $this->documentFieldHelper;
  539.     }
  540.     /**
  541.      * @return DataObjectFieldHelper
  542.      */
  543.     public function getObjectFieldHelper()
  544.     {
  545.         return $this->objectFieldHelper;
  546.     }
  547.     public function getQueryTypeGeneratorFactories(): ContainerInterface
  548.     {
  549.         return $this->dataObjectQueryTypeGeneratorFactories;
  550.     }
  551.     public function getQueryOperatorFactories(): ContainerInterface
  552.     {
  553.         return $this->dataObjectQueryOperatorFactories;
  554.     }
  555.     public function getLocaleService(): LocaleServiceInterface
  556.     {
  557.         return $this->localeService;
  558.     }
  559.     public function getModelFactory(): Factory
  560.     {
  561.         return $this->modelFactory;
  562.     }
  563.     /**
  564.      * @return Translator
  565.      */
  566.     public function getTranslator()
  567.     {
  568.         return $this->translator;
  569.     }
  570.     /**
  571.      * @param array $dataTypes
  572.      */
  573.     public function registerDataObjectDataTypes($dataTypes)
  574.     {
  575.         $this->dataObjectDataTypes $dataTypes;
  576.     }
  577.     /**
  578.      * @param array $dataTypes
  579.      */
  580.     public function registerAssetDataTypes($dataTypes)
  581.     {
  582.         $this->assetDataTypes $dataTypes;
  583.     }
  584.     public function registerTranslationDataTypes(array $dataTypes)
  585.     {
  586.         $this->translationDataTypes $dataTypes;
  587.     }
  588.     /**
  589.      * @param array $dataTypes
  590.      */
  591.     public function registerDocumentDataTypes($dataTypes)
  592.     {
  593.         $this->documentDataTypes $dataTypes;
  594.     }
  595.     /**
  596.      * @param array $dataTypes
  597.      */
  598.     public function registerPropertyDataTypes($dataTypes)
  599.     {
  600.         $this->propertyDataTypes $dataTypes;
  601.     }
  602.     /**
  603.      * @param array $dataTypes
  604.      */
  605.     public function registerClassificationStoreDataTypes($dataTypes)
  606.     {
  607.         $this->classificationStoreDataTypes $dataTypes;
  608.     }
  609.     /**
  610.      * @param string $typeName
  611.      *
  612.      * @return mixed
  613.      *
  614.      * @throws \Exception
  615.      */
  616.     public function getAssetTypeDefinition($typeName)
  617.     {
  618.         if (isset($this->assetDataTypes[$typeName])) {
  619.             return $this->assetDataTypes[$typeName];
  620.         }
  621.         throw new ClientSafeException('unknown asset type: ' $typeName);
  622.     }
  623.     /**
  624.      * @param string $typeName
  625.      *
  626.      * @return mixed
  627.      *
  628.      * @throws \Exception
  629.      */
  630.     public function getClassificationStoreTypeDefinition($typeName)
  631.     {
  632.         if (isset($this->classificationStoreDataTypes[$typeName])) {
  633.             return $this->classificationStoreDataTypes[$typeName];
  634.         }
  635.         throw new ClientSafeException('unknown classificationstore type: ' $typeName);
  636.     }
  637.     /**
  638.      * @param string $typeName
  639.      *
  640.      * @return mixed
  641.      *
  642.      * @throws \Exception
  643.      */
  644.     public function getDataObjectTypeDefinition($typeName)
  645.     {
  646.         if (isset($this->dataObjectDataTypes[$typeName])) {
  647.             return $this->dataObjectDataTypes[$typeName];
  648.         }
  649.         throw new ClientSafeException('unknown dataobject type: ' $typeName);
  650.     }
  651.     /**
  652.      * @param string $typeName
  653.      *
  654.      * @return mixed
  655.      *
  656.      * @throws \Exception
  657.      */
  658.     public function getDocumentTypeDefinition($typeName)
  659.     {
  660.         if (isset($this->documentDataTypes[$typeName])) {
  661.             return $this->documentDataTypes[$typeName];
  662.         }
  663.         throw new ClientSafeException('unknown document type: ' $typeName);
  664.     }
  665.     /**
  666.      * @param string $typeName
  667.      *
  668.      * @return mixed
  669.      *
  670.      * @throws \Exception
  671.      */
  672.     public function getPropertyTypeDefinition($typeName)
  673.     {
  674.         if (isset($this->propertyDataTypes[$typeName])) {
  675.             return $this->propertyDataTypes[$typeName];
  676.         }
  677.         throw new ClientSafeException('unknown property type: ' $typeName);
  678.     }
  679.     /**
  680.      * gets value for given object and getter, including inherited values
  681.      *
  682.      * @static
  683.      *
  684.      * @param Concrete $object
  685.      * @param string $key
  686.      * @param string|null $brickType
  687.      * @param string|null $brickKey
  688.      * @param Data|null $fieldDefinition
  689.      *
  690.      * @return \stdclass, value and objectid where the value comes from
  691.      */
  692.     public static function getValueForObject($object$key$brickType null$brickKey null$fieldDefinition null$context = [], $brickDescriptor null$args = [])
  693.     {
  694.         //TODO once this gets integrated into the core, share the code with Service::getValueFromObject
  695.         $getter 'get' ucfirst($key);
  696.         $value $object->$getter();
  697.         if (!empty($value) && !empty($brickType)) {
  698.             $getBrickType 'get' ucfirst($brickType);
  699.             $value $value->$getBrickType();
  700.             if (!empty($value) && !empty($brickKey)) {
  701.                 if ($brickDescriptor) {
  702.                     $innerContainer $brickDescriptor['innerContainer'] ? $brickDescriptor['innerContainer'] : 'localizedfields';
  703.                     $localizedFields $value->{'get' ucfirst($innerContainer)}();
  704.                     $brickDefinition Definition::getByKey($brickType);
  705.                     /** @var Data\Localizedfields $fieldDefinitionLocalizedFields */
  706.                     $fieldDefinitionLocalizedFields $brickDefinition->getFieldDefinition('localizedfields');
  707.                     $fieldDefinition $fieldDefinitionLocalizedFields->getFieldDefinition($brickKey);
  708.                     $value $localizedFields->getLocalizedValue($brickDescriptor['brickfield'], isset($args['language']) ? $args['language'] : null);
  709.                 } else {
  710.                     $brickFieldGetter 'get' ucfirst($brickKey);
  711.                     $value $value->$brickFieldGetter();
  712.                 }
  713.             }
  714.         }
  715.         if (!$fieldDefinition) {
  716.             $fieldDefinition $object->getClass()->getFieldDefinition($key$context);
  717.         }
  718.         if (!empty($brickType) && !empty($brickKey) && !$brickDescriptor) {
  719.             $brickClass Definition::getByKey($brickType);
  720.             $context = ['object' => $object'outerFieldname' => $key];
  721.             $fieldDefinition $brickClass->getFieldDefinition($brickKey$context);
  722.         }
  723.         if ($fieldDefinition->isEmpty($value)) {
  724.             $parent \Pimcore\Model\DataObject\Service::hasInheritableParentObject($object);
  725.             if (!empty($parent)) {
  726.                 if (!($parent instanceof Concrete)) {
  727.                     $parent Concrete::getById($parent->getId());
  728.                 }
  729.                 return self::getValueForObject($parent$key$brickType$brickKey$fieldDefinition$context$brickDescriptor);
  730.             }
  731.         }
  732.         return $value;
  733.     }
  734.     /**
  735.      * @param Concrete|null $object
  736.      * @param string $attribute
  737.      * @param \Closure $callback
  738.      *
  739.      * @return \stdclass|null
  740.      *
  741.      * @throws \Exception
  742.      */
  743.     public static function setValue($object$attribute$callback)
  744.     {
  745.         $result null;
  746.         $setter $attribute 'set' ucfirst($attribute) : $attribute;
  747.         if (!$object) {
  748.             return null;
  749.         }
  750.         $container $object;
  751.         $attributeParts explode('~'$attribute);
  752.         if (substr($attribute01) === '~') {
  753.             // key value, ignore for now
  754.         } elseif (count($attributeParts) > 1) {
  755.             // TODO once the datahub gets integrated into the core we should try to share this code
  756.             // with Pimcore\Model\DataObject\Service::gridObjectData
  757.             $context = ['object' => $object];
  758.             $brickDescriptor null;
  759.             // brick
  760.             $brickType $attributeParts[0];
  761.             if (strpos($brickType'?') !== false) {
  762.                 $brickDescriptor substr($brickType1);
  763.                 $brickDescriptor json_decode($brickDescriptortrue);
  764.                 $brickType $brickDescriptor['containerKey'];
  765.             }
  766.             $brickKey $attributeParts[1];
  767.             $key \Pimcore\Model\DataObject\Service::getFieldForBrickType($object->getclass(), $brickType);
  768.             $brickClass Definition::getByKey($brickType);
  769.             $context['outerFieldname'] = $key;
  770.             if ($brickDescriptor) {
  771.                 $def $brickClass->getFieldDefinition($brickKey);
  772.                 if (!$def) {
  773.                     $innerContainer $brickDescriptor['innerContainer'] ? $brickDescriptor['innerContainer'] : 'localizedfields';
  774.                     /** @var Data\Localizedfields $localizedFields */
  775.                     $localizedFields $brickClass->getFieldDefinition($innerContainer);
  776.                     $def $localizedFields->getFieldDefinition($brickDescriptor['brickfield']);
  777.                 }
  778.             } else {
  779.                 $def $brickClass->getFieldDefinition($brickKey$context);
  780.             }
  781.             if (!empty($key)) {
  782.                 // if the definition is not set try to get the definition from localized fields
  783.                 if (!$def) {
  784.                     /** @var Data\Localizedfields|null $locFields */
  785.                     $locFields $object->getClass()->getFieldDefinition('localizedfields');
  786.                     if ($locFields) {
  787.                         $def $locFields->getFieldDefinition($key$context);
  788.                     }
  789.                 }
  790.                 $brickGetter 'get' ucfirst($key);
  791.                 $brickContainer $object->$brickGetter();
  792.                 $subBrickGetter 'get' ucfirst($brickType);
  793.                 $subBrickSetter 'set' ucfirst($brickType);
  794.                 $subBrickType $brickContainer->$subBrickGetter();
  795.                 if (!$subBrickType) {
  796.                     /** @var AbstractData $brickClass */
  797.                     $brickClass 'Pimcore\\Model\\DataObject\\Objectbrick\\Data\\' ucfirst($brickType);
  798.                     $subBrickType = new $brickClass($object);
  799.                     $subBrickSetter 'set' ucfirst($brickType);
  800.                     $brickContainer->$subBrickSetter($subBrickType);
  801.                 }
  802.                 $innerSetter 'set' ucfirst($def->getName());
  803.                 $result $callback($subBrickType$innerSetter);
  804.                 $brickContainer->$subBrickSetter($subBrickType);
  805.                 return $result;
  806.             }
  807.         } elseif (method_exists($container$setter)) {
  808.             $result $callback($container$setter);
  809.         }
  810.         return $result;
  811.     }
  812.     /**
  813.      * @param BaseDescriptor $descriptor
  814.      * @param Data $fieldDefinition
  815.      * @param string $attribute
  816.      * @param array $args
  817.      *
  818.      * @return mixed
  819.      */
  820.     public static function resolveValue(BaseDescriptor $descriptorData $fieldDefinition$attribute$args = [])
  821.     {
  822.         $getter 'get' ucfirst($fieldDefinition->getName());
  823.         $objectId $descriptor['id'];
  824.         $object Concrete::getById($objectId);
  825.         if (!$object) {
  826.             return null;
  827.         }
  828.         $result null;
  829.         $container $object;
  830.         $attributeParts explode('~'$attribute);
  831.         if ($descriptor instanceof FieldcollectionDescriptor) {
  832.             $descriptorData $descriptor->getArrayCopy();
  833.             $fcFieldNameGetter 'get' ucfirst($descriptorData['__fcFieldname']);
  834.             $fcData $object->$fcFieldNameGetter();
  835.             if ($fcData) {
  836.                 $items $fcData->getItems();
  837.                 $idx $descriptorData['__itemIdx'];
  838.                 $itemData $items[$idx];
  839.                 if (is_array($args) && isset($args['language'])) {
  840.                     $result $itemData->$getter($args['language']);
  841.                 } else {
  842.                     $result $itemData->$getter();
  843.                 }
  844.             }
  845.         } elseif ($descriptor instanceof BlockDescriptor) {
  846.             $descriptorData $descriptor->getArrayCopy();
  847.             $blockData null;
  848.             if (isset($descriptorData['__fcFieldname']) && $descriptorData['__fcFieldname']) {
  849.                 $fcFieldNameGetter 'get' ucfirst($descriptorData['__fcFieldname']);
  850.                 $fcData $object->$fcFieldNameGetter();
  851.                 if ($fcData) {
  852.                     $items $fcData->getItems();
  853.                     $idx $descriptorData['__itemIdx'];
  854.                     $itemData $items[$idx];
  855.                     $result = [];
  856.                     $blockGetter 'get' ucfirst($descriptorData['__blockName']);
  857.                     $blockData call_user_func_array([$itemData$blockGetter], $descriptorData['args'] ?? []);
  858.                 }
  859.             } elseif (isset($descriptorData['__brickType']) && $descriptorData['__brickType']) {
  860.                 $context = ['object' => $object];
  861.                 $brickDescriptor null;
  862.                 $brickType $descriptorData['__brickType'];
  863.                 $brickKey $descriptorData['__brickKey'];
  864.                 $key \Pimcore\Model\DataObject\Service::getFieldForBrickType($object->getclass(), $brickType);
  865.                 $brickClass Definition::getByKey($brickType);
  866.                 if (!$brickClass) {
  867.                     return null;
  868.                 }
  869.                 $context['outerFieldname'] = $key;
  870.                 $def $brickClass->getFieldDefinition($brickKey$context);
  871.                 if (!$def) {
  872.                     return null;
  873.                 }
  874.                 if (!empty($key)) {
  875.                     $blockData self::getValueForObject($object$key$brickType$brickKey$def$context$brickDescriptor$args);
  876.                 }
  877.             } else {
  878.                 $blockGetter 'get'.ucfirst($descriptorData['__blockName']);
  879.                 $isLocalizedField self::isLocalizedField($container$fieldDefinition->getName());
  880.                 $blockData $object->$blockGetter($isLocalizedField && isset($descriptorData['args']['language']) ? $descriptorData['args']['language'] : null);
  881.             }
  882.             if ($blockData) {
  883.                 $index $descriptorData['__blockIndex'];
  884.                 $itemData $blockData[$index];
  885.                 $result $itemData[$descriptorData['__blockFieldName']]->getData();
  886.                 if (isset($descriptorData['__localized']) && $descriptorData['__localized']) {
  887.                     $result $result->getLocalizedValue($descriptorData['__localized'], $args['language'] ?? null);
  888.                 }
  889.             }
  890.         } elseif (substr($attribute01) == '~') {
  891.             // key value, ignore for now
  892.         } elseif (count($attributeParts) > 1) {
  893.             // TODO once the datahub gets integrated into the core we should try to share this code
  894.             // with Pimcore\Model\DataObject\Service::gridObjectData
  895.             $context = ['object' => $object];
  896.             $brickDescriptor null;
  897.             // brick
  898.             $brickType $attributeParts[0];
  899.             if (strpos($brickType'?') !== false) {
  900.                 $brickDescriptor substr($brickType1);
  901.                 $brickDescriptor json_decode($brickDescriptortrue);
  902.                 $brickType $brickDescriptor['containerKey'];
  903.             }
  904.             $brickKey $attributeParts[1];
  905.             $key \Pimcore\Model\DataObject\Service::getFieldForBrickType($object->getclass(), $brickType);
  906.             $brickClass Definition::getByKey($brickType);
  907.             $context['outerFieldname'] = $key;
  908.             if ($brickDescriptor) {
  909.                 $innerContainer $brickDescriptor['innerContainer'] ? $brickDescriptor['innerContainer'] : 'localizedfields';
  910.                 /** @var Data\Localizedfields $localizedFields */
  911.                 $localizedFields $brickClass->getFieldDefinition($innerContainer);
  912.                 $def $localizedFields->getFieldDefinition($brickDescriptor['brickfield']);
  913.             } else {
  914.                 $def $brickClass->getFieldDefinition($brickKey$context);
  915.             }
  916.             if (!empty($key)) {
  917.                 // if the definition is not set try to get the definition from localized fields
  918.                 if (!$def) {
  919.                     /** @var Data\Localizedfields|null $locFields */
  920.                     $locFields $object->getClass()->getFieldDefinition('localizedfields');
  921.                     if ($locFields) {
  922.                         $def $locFields->getFieldDefinition($key$context);
  923.                     }
  924.                 }
  925.                 $value self::getValueForObject($object$key$brickType$brickKey$def$context$brickDescriptor$args);
  926.                 return $value;
  927.             }
  928.         } elseif (method_exists($container$getter)) {
  929.             $isLocalizedField self::isLocalizedField($container$fieldDefinition->getName());
  930.             $result $container->$getter($isLocalizedField && isset($args['language']) ? $args['language'] : null);
  931.         }
  932.         return $result;
  933.     }
  934.     /**
  935.      * Check whether given field in container is localized
  936.      *
  937.      * @param object $container
  938.      * @param string $fieldName
  939.      *
  940.      * @return bool
  941.      */
  942.     private static function isLocalizedField($container$fieldName): bool
  943.     {
  944.         $containerDefinition null;
  945.         if ($container instanceof Concrete) {
  946.             $containerDefinition $container->getClass();
  947.         } elseif ($container instanceof AbstractData) {
  948.             $containerDefinition $container->getDefinition();
  949.         }
  950.         if ($containerDefinition) {
  951.             /** @var Data\Localizedfields|null $lfDefs */
  952.             $lfDefs $containerDefinition->getFieldDefinition('localizedfields');
  953.             if ($lfDefs?->getFieldDefinition($fieldName)) {
  954.                 return true;
  955.             }
  956.         }
  957.         return false;
  958.     }
  959.     public function getDataObjectMutationTypeGeneratorFactories(): ContainerInterface
  960.     {
  961.         return $this->dataObjectMutationTypeGeneratorFactories;
  962.     }
  963.     public function setDataObjectMutationTypeGeneratorFactories(ContainerInterface $dataObjectMutationTypeGeneratorFactories): void
  964.     {
  965.         $this->dataObjectMutationTypeGeneratorFactories $dataObjectMutationTypeGeneratorFactories;
  966.     }
  967.     public function getDataObjectMutationOperatorFactories(): ContainerInterface
  968.     {
  969.         return $this->dataObjectMutationOperatorFactories;
  970.     }
  971.     public function setDataObjectMutationOperatorFactories(ContainerInterface $dataObjectMutationOperatorFactories): void
  972.     {
  973.         $this->dataObjectMutationOperatorFactories $dataObjectMutationOperatorFactories;
  974.     }
  975.     public function getDataObjectDataTypes(): array
  976.     {
  977.         return $this->dataObjectDataTypes;
  978.     }
  979.     /**
  980.      * @param mixed $data
  981.      * @param ElementInterface $target
  982.      * @param array $args
  983.      * @param array $context
  984.      * @param ResolveInfo|null $resolveInfo
  985.      */
  986.     public function extractData($data$target$args = [], $context = [], ResolveInfo $resolveInfo null)
  987.     {
  988.         $fieldHelper null;
  989.         if ($target instanceof Document) {
  990.             $fieldHelper $this->getDocumentFieldHelper();
  991.         } elseif ($target instanceof Asset) {
  992.             $fieldHelper $this->getAssetFieldHelper();
  993.         } elseif ($target instanceof AbstractObject) {
  994.             $fieldHelper $this->getObjectFieldHelper();
  995.         }
  996.         if ($fieldHelper) {
  997.             $fieldHelper->extractData($data$target$args$context$resolveInfo);
  998.         }
  999.     }
  1000.     /**
  1001.      * @param string $type
  1002.      *
  1003.      * @return bool
  1004.      */
  1005.     public function querySchemaEnabled(string $type)
  1006.     {
  1007.         $context RuntimeCache::get('datahub_context');
  1008.         /** @var Configuration $configuration */
  1009.         $configuration $context['configuration'];
  1010.         if ($type === 'object') {
  1011.             $types $configuration->getConfiguration()['schema']['queryEntities'];
  1012.             $enabled count($types) > 0;
  1013.         } else {
  1014.             $enabled $configuration->getSpecialEntities()[$type]['read'] ?? false;
  1015.         }
  1016.         return $enabled;
  1017.     }
  1018. }