|
11 | 11 | use Ibexa\Core\FieldType; |
12 | 12 | use Ibexa\GraphQL\DataLoader\ContentLoader; |
13 | 13 | use Ibexa\GraphQL\ItemFactory; |
| 14 | +use Ibexa\GraphQL\Relay\PageAwareConnection; |
14 | 15 | use Ibexa\GraphQL\Value\Field; |
| 16 | +use Overblog\GraphQLBundle\Definition\Argument; |
| 17 | +use Overblog\GraphQLBundle\Relay\Connection\Paginator; |
15 | 18 |
|
16 | 19 | final class RelationFieldResolver |
17 | 20 | { |
18 | | - /** @var \Ibexa\GraphQL\DataLoader\ContentLoader */ |
19 | | - private $contentLoader; |
| 21 | + public const DEFAULT_LIMIT = 25; |
20 | 22 |
|
21 | | - /** @var \Ibexa\GraphQL\ItemFactory */ |
22 | | - private $itemFactory; |
| 23 | + private ContentLoader $contentLoader; |
23 | 24 |
|
24 | | - public function __construct(ContentLoader $contentLoader, ItemFactory $relatedContentItemFactory) |
25 | | - { |
| 25 | + private ItemFactory $itemFactory; |
| 26 | + |
| 27 | + private bool $enablePagination; |
| 28 | + |
| 29 | + public function __construct( |
| 30 | + ContentLoader $contentLoader, |
| 31 | + ItemFactory $relatedContentItemFactory, |
| 32 | + bool $enablePagination |
| 33 | + ) { |
26 | 34 | $this->contentLoader = $contentLoader; |
27 | 35 | $this->itemFactory = $relatedContentItemFactory; |
| 36 | + $this->enablePagination = $enablePagination; |
28 | 37 | } |
29 | 38 |
|
30 | | - public function resolveRelationFieldValue(Field $field, $multiple = false) |
| 39 | + public function resolveRelationFieldValue(Field $field, $multiple = false, Argument $args) |
31 | 40 | { |
32 | 41 | $destinationContentIds = $this->getContentIds($field); |
33 | 42 |
|
34 | 43 | if (empty($destinationContentIds) || array_key_exists(0, $destinationContentIds) && null === $destinationContentIds[0]) { |
35 | 44 | return $multiple ? [] : null; |
36 | 45 | } |
37 | 46 |
|
38 | | - $contentItems = $this->contentLoader->find(new Query( |
| 47 | + $query = new Query( |
39 | 48 | ['filter' => new Query\Criterion\ContentId($destinationContentIds)] |
40 | | - )); |
| 49 | + ); |
41 | 50 |
|
42 | 51 | if ($multiple) { |
43 | | - return array_map( |
44 | | - function ($contentId) use ($contentItems) { |
45 | | - return $this->itemFactory->fromContent( |
46 | | - $contentItems[array_search($contentId, array_column($contentItems, 'id'))] |
47 | | - ); |
48 | | - }, |
49 | | - $destinationContentIds |
| 52 | + if (!$this->enablePagination) { |
| 53 | + $contentItems = $this->contentLoader->find($query); |
| 54 | + |
| 55 | + return array_map( |
| 56 | + function ($contentId) use ($contentItems) { |
| 57 | + return $this->itemFactory->fromContent( |
| 58 | + $contentItems[array_search($contentId, array_column($contentItems, 'id'))] |
| 59 | + ); |
| 60 | + }, |
| 61 | + $destinationContentIds |
| 62 | + ); |
| 63 | + } |
| 64 | + |
| 65 | + $paginator = new Paginator(function ($offset, $limit) use ($query) { |
| 66 | + $query->offset = $offset; |
| 67 | + $query->limit = $limit ?? self::DEFAULT_LIMIT; |
| 68 | + $contentItems = $this->contentLoader->find($query); |
| 69 | + |
| 70 | + return array_map( |
| 71 | + function ($content) { |
| 72 | + return $this->itemFactory->fromContent( |
| 73 | + $content |
| 74 | + ); |
| 75 | + }, |
| 76 | + $contentItems |
| 77 | + ); |
| 78 | + }); |
| 79 | + |
| 80 | + return PageAwareConnection::fromConnection( |
| 81 | + $paginator->auto( |
| 82 | + $args, |
| 83 | + function () use ($query) { |
| 84 | + return $this->contentLoader->count($query); |
| 85 | + } |
| 86 | + ), |
| 87 | + $args |
50 | 88 | ); |
51 | 89 | } |
52 | 90 |
|
| 91 | + $query->limit = 1; |
| 92 | + $contentItems = $this->contentLoader->find($query); |
| 93 | + |
53 | 94 | return $contentItems[0] ? $this->itemFactory->fromContent($contentItems[0]) : null; |
54 | 95 | } |
55 | 96 |
|
|
0 commit comments