Skip to content

Commit

Permalink
Merge pull request #9 from TomHAnderson/hotfix/cleanup
Browse files Browse the repository at this point in the history
Hotfix/cleanup
  • Loading branch information
TomHAnderson authored Jun 23, 2018
2 parents 59aca60 + 9068484 commit bfeec3b
Show file tree
Hide file tree
Showing 12 changed files with 190 additions and 73 deletions.
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -375,3 +375,28 @@ Resolve Post

The `EntityResolveAbstractFactory::RESOLVE_POST` event allows you to modify the values
returned from the ResolveLoader via an ArrayObject or replace the values.


Internals
=========


Hydrator Extract Tool
---------------------

All hydrator extract operations are handled through the Hydrator Extract Tool. This tool is engineered to be overridden
thanks to a service manager alias. Should you find the need to add custom caching to hydrator results this is where to
do it. To register a custom hydrator extract tool use
```php
'aliases' => [
'ZF\Doctrine\GraphQL\Hydrator\HydratorExtractTool' => CustomExtractTool::class,
],
```


Field Resolver
--------------

This standard part of GraphQL resolves individual fields and is where the built in caching resides. This resolver uses
the Hydrator Extract Tool and returns one field value at a time. For high performance writing your own Field Resolver is an
option. To register a custom field resolver use `GraphQL::setDefaultFieldResolver($fieldResolver);`
5 changes: 5 additions & 0 deletions src/ConfigProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,12 @@ public function __invoke()
public function getDependencyConfig()
{
return [
'aliases' => [
'ZF\Doctrine\GraphQL\Hydrator\HydratorExtractTool' => Hydrator\HydratorExtractToolDefault::class,
],
'factories' => [
Hydrator\HydratorExtractToolDefault::class => Hydrator\HydratorExtractToolDefaultFactory::class,

Hydrator\Filter\FilterDefault::class => InvokableFactory::class,
Hydrator\Filter\Password::class => InvokableFactory::class,
Hydrator\Strategy\ToBoolean::class => InvokableFactory::class,
Expand Down
19 changes: 8 additions & 11 deletions src/Criteria/FilterTypeAbstractFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,21 +53,18 @@ public function __invoke(ContainerInterface $container, $requestedName, array $o

$config = $container->get('config');
$fields = [];
$hydratorManager = $container->get('HydratorManager');
$typeManager = $container->get(TypeManager::class);
$filterManager = $container->get(FilterManager::class);
$orderByManager = $container->get(OrderByManager::class);

$hydratorAlias = 'ZF\\Doctrine\\GraphQL\\Hydrator\\' . str_replace('\\', '_', $requestedName);
$hydratorConfig = $config['zf-doctrine-graphql-hydrator'][$hydratorAlias][$options['hydrator_section']];

$objectManager = $container->get($hydratorConfig['object_manager']);
$hydrator = $hydratorManager->get($hydratorAlias);

// Create an instance of the entity in order to get fields from the hydrator.
$instantiator = new Instantiator();
$entity = $instantiator->instantiate($requestedName);
$entityFields = array_keys($hydrator->extract($entity));
$hydratorExtractTool = $container->get('ZF\\Doctrine\\GraphQL\\Hydrator\\HydratorExtractTool');
$objectManager = $container
->get(
$config['zf-doctrine-graphql-hydrator'][$hydratorAlias][$options['hydrator_section']]['object_manager']
);

// Get an array of the hydrator fields
$entityFields = $hydratorExtractTool->getFieldArray($requestedName, $hydratorAlias, $options);

$classMetadata = $objectManager->getClassMetadata($requestedName);

Expand Down
14 changes: 7 additions & 7 deletions src/Field/FieldResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@
use Doctrine\Common\Util\ClassUtils;
use GraphQL\Type\Definition\ResolveInfo;
use ZF\Doctrine\GraphQL\Context;
use ZF\Doctrine\GraphQL\Hydrator\HydratorExtractToolInterface;

/**
* A field resolver which uses the Doctrine hydrator. Can be used byReference or byValue.
*/
class FieldResolver
{
private $hydratorManager;
private $hydratorExtractTool;

/**
* Cache all hydrator extract operations based on spl object hash
Expand All @@ -24,9 +25,9 @@ class FieldResolver
*/
private $extractValues = [];

public function __construct(HydratorPluginManager $hydratorManager)
public function __construct(HydratorExtractToolInterface $hydratorExtractTool)
{
$this->hydratorManager = $hydratorManager;
$this->hydratorExtractTool = $hydratorExtractTool;
}

public function __invoke($source, $args, Context $context, ResolveInfo $info)
Expand All @@ -50,8 +51,8 @@ public function __invoke($source, $args, Context $context, ResolveInfo $info)
$this->extractValues = [];
}

$hydrator = $this->hydratorManager->get($hydratorAlias);
$this->extractValues[$splObjectHash] = $hydrator->extract($source);
$this->extractValues[$splObjectHash]
= $this->hydratorExtractTool->extract($source, $hydratorAlias, $context);

return $this->extractValues[$splObjectHash][$info->fieldName] ?? null;
}
Expand All @@ -61,8 +62,7 @@ public function __invoke($source, $args, Context $context, ResolveInfo $info)
return $this->extractValues[$splObjectHash][$info->fieldName] ?? null;
}

$hydrator = $this->hydratorManager->get($hydratorAlias);
$this->extractValues[$splObjectHash] = $hydrator->extract($source);
$this->extractValues[$splObjectHash] = $this->hydratorExtractTool->extract($source, $hydratorAlias, $context);

return $this->extractValues[$splObjectHash][$info->fieldName] ?? null;
}
Expand Down
4 changes: 2 additions & 2 deletions src/Field/FieldResolverFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ public function __invoke(
$requestedName,
array $options = null
) {
$hydratorManager = $container->get('HydratorManager');
$hydratorExtractTool = $container->get('ZF\\Doctrine\\GraphQL\\Hydrator\\HydratorExtractTool');

return new FieldResolver($hydratorManager);
return new FieldResolver($hydratorExtractTool);
}
}
19 changes: 8 additions & 11 deletions src/Filter/FilterTypeAbstractFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
use Interop\Container\ContainerInterface;
use Zend\ServiceManager\AbstractFactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Doctrine\Instantiator\Instantiator;
use Doctrine\ORM\Mapping\MappingException;
use GraphQL\Type\Definition\Type;
use ZF\Doctrine\QueryBuilder\Filter\Service\ORMFilterManager;
Expand Down Expand Up @@ -54,22 +53,20 @@ public function __invoke(ContainerInterface $container, $requestedName, array $o

$fields = [];
$config = $container->get('config');
$hydratorManager = $container->get('HydratorManager');
$typeManager = $container->get(TypeManager::class);

$hydratorAlias = 'ZF\\Doctrine\\GraphQL\\Hydrator\\' . str_replace('\\', '_', $requestedName);
$hydratorConfig = $config['zf-doctrine-graphql-hydrator'][$hydratorAlias][$options['hydrator_section']];
$hydrator = $hydratorManager->build($hydratorAlias, $options);

$objectManager = $container->get($hydratorConfig['object_manager']);
$hydratorExtractTool = $container->get('ZF\\Doctrine\\GraphQL\\Hydrator\\HydratorExtractTool');
$objectManager = $container
->get(
$config['zf-doctrine-graphql-hydrator'][$hydratorAlias][$options['hydrator_section']]['object_manager']
);
$filterManager = $container->get(ORMFilterManager::class);
$criteriaFilterManager = $container->get(CriteriaFilterManager::class);
$orderByManager = $container->get(ORMOrderByManager::class);

// Create an instance of the entity in order to get fields from the hydrator.
$instantiator = new Instantiator();
$entity = $instantiator->instantiate($requestedName);
$entityFields = array_keys($hydrator->extract($entity));
// Get an array of the hydrator fields
$entityFields = $hydratorExtractTool->getFieldArray($requestedName, $hydratorAlias, $options);

$references = [];

$classMetadata = $objectManager->getClassMetadata($requestedName);
Expand Down
75 changes: 75 additions & 0 deletions src/Hydrator/HydratorExtractToolDefault.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php

namespace ZF\Doctrine\GraphQL\Hydrator;

use Zend\Hydrator\HydratorPluginManager;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Instantiator\Instantiator;
use ZF\Doctrine\GraphQL\Context;

/**
* This tool centralizes all extract operations for the module.
* By doing so caching and optimization of operations can be applied
* by overriding the this class alias in the config.
*/
class HydratorExtractToolDefault implements
HydratorExtractToolInterface
{
protected $hydratorManager;

public function __construct(HydratorPluginManager $hydratorManager)
{
$this->hydratorManager = $hydratorManager;
}

// Extract an array of entities and return a collection
public function extractToCollection($entityArray, string $hydratorAlias, $options)
{
$options = $this->optionsToArray($options);
$hydrator = $this->hydratorManager->build($hydratorAlias, $options);

$resultCollection = new ArrayCollection();
foreach ($entityArray as $value) {
if (is_array($value)) {
$resultCollection->add($value);
} else {
$resultCollection->add($hydrator->extract($value));
}
}

return $resultCollection;
}

// Extract a single entity
public function extract($entity, string $hydratorAlias, $options)
{
if (is_array($entity)) {
return $entity;
}

$options = $this->optionsToArray($options);
$hydrator = $this->hydratorManager->build($hydratorAlias, $options);

return $hydrator->extract($entity);
}

public function getFieldArray(string $entityClassName, string $hydratorAlias, $options)
{
$instantiator = new Instantiator();
$entity = $instantiator->instantiate($entityClassName);

$options = $this->optionsToArray($options);
$hydrator = $this->hydratorManager->build($hydratorAlias, $options);

return array_keys($hydrator->extract($entity));
}

private function optionsToArray($options)
{
if ($options instanceof Context) {
$options = $options->toArray();
}

return $options;
}
}
18 changes: 18 additions & 0 deletions src/Hydrator/HydratorExtractToolDefaultFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace ZF\Doctrine\GraphQL\Hydrator;

use Interop\Container\ContainerInterface;

class HydratorExtractToolDefaultFactory
{
public function __invoke(
ContainerInterface $container,
$requestedName,
array $options = null
) {
$hydratorManager = $container->get('HydratorManager');

return new HydratorExtractToolDefault($hydratorManager);
}
}
9 changes: 9 additions & 0 deletions src/Hydrator/HydratorExtractToolInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

namespace ZF\Doctrine\GraphQL\Hydrator;

interface HydratorExtractToolInterface
{
public function extract($entity, string $hydratorAlias, $options);
public function extractToCollection($entityArray, string $hydratorAlias, $options);
}
22 changes: 10 additions & 12 deletions src/Resolve/EntityResolveAbstractFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

use Closure;
use Exception;
use ArrayObject;
use Interop\Container\ContainerInterface;
use Zend\ServiceManager\AbstractFactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
Expand Down Expand Up @@ -80,23 +79,25 @@ public function __invoke(ContainerInterface $container, $requestedName, array $o
$this->createEventManager($container->get('SharedEventManager'));

$config = $container->get('config');
$hydratorManager = $container->get('HydratorManager');
$hydratorAlias = 'ZF\\Doctrine\\GraphQL\\Hydrator\\' . str_replace('\\', '_', $requestedName);
$hydrator = $hydratorManager->build($hydratorAlias, $options);
$hydratorConfig = $config['zf-doctrine-graphql-hydrator'][$hydratorAlias][$options['hydrator_section']];
$hydratorExtractTool = $container->get('ZF\\Doctrine\\GraphQL\\Hydrator\\HydratorExtractTool');
$filterManager = $container->get(ORMFilterManager::class);
$orderByManager = $container->get(ORMOrderByManager::class);
$criteriaFilterManager = $container->get(CriteriaFilterManager::class);
$criteriaBuilder = $container->get(CriteriaBuilder::class);
$objectManager = $container->get($hydratorConfig['object_manager']);
$objectManager = $container
->get(
$config['zf-doctrine-graphql-hydrator'][$hydratorAlias][$options['hydrator_section']]['object_manager']
);

$instance = function (
$obj,
$args,
$context
) use (
$options,
$hydrator,
$hydratorAlias,
$hydratorExtractTool,
$objectManager,
$requestedName,
$filterManager,
Expand All @@ -112,7 +113,7 @@ public function __invoke(ContainerInterface $container, $requestedName, array $o
'object' => $obj,
'arguments' => $args,
'context' => $context,
'hydrator' => $hydrator,
'hydratorAlias' => $hydratorAlias,
'objectManager' => $objectManager,
'entityClassName' => $requestedName,
]
Expand Down Expand Up @@ -290,10 +291,7 @@ public function __invoke(ContainerInterface $container, $requestedName, array $o
$results = $queryBuilder->getQuery()->getResult();

// Build hydrated result collection
$resultCollection = new ArrayCollection();
foreach ($results as $key => $value) {
$resultCollection->add($hydrator->extract($value));
}
$resultCollection = $hydratorExtractTool->extractToCollection($results, $hydratorAlias, $options);

// Criteria post filter
if ($criteriaArray) {
Expand Down Expand Up @@ -322,7 +320,7 @@ public function __invoke(ContainerInterface $container, $requestedName, array $o
'arguments' => $args,
'context' => $context,
'resultCollection' => $resultCollection,
'hydrator' => $hydrator,
'hydratorAlias' => $hydratorAlias,
'objectManager' => $objectManager,
'queryBuilder' => $queryBuilder,
'entityClassName' => $requestedName,
Expand Down
Loading

0 comments on commit bfeec3b

Please sign in to comment.