Completed
Pull Request — 8.x-3.x (#481)
by Sebastian
05:33
created

SubRequestBuffer::resolveBufferArray()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 35
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 20
nc 4
nop 1
dl 0
loc 35
rs 8.5806
c 0
b 0
f 0
1
<?php
2
3
namespace Drupal\graphql\GraphQL\Buffers;
4
5
use Drupal\Core\Url;
6
use Symfony\Component\HttpFoundation\Request;
7
use Symfony\Component\HttpFoundation\RequestStack;
8
use Symfony\Component\HttpKernel\HttpKernelInterface;
9
10
class SubRequestBuffer extends BufferBase {
11
12
  /**
13
   * The http kernel service.
14
   *
15
   * @var \Symfony\Component\HttpKernel\HttpKernelInterface
16
   */
17
  protected $httpKernel;
18
19
  /**
20
   * The request stack service.
21
   *
22
   * @var \Symfony\Component\HttpFoundation\RequestStack
23
   */
24
  protected $requestStack;
25
26
  /**
27
   * SubrequestBuffer constructor.
28
   *
29
   * @param \Symfony\Component\HttpKernel\HttpKernelInterface $httpKernel
30
   *   The http kernel service.
31
   * @param \Symfony\Component\HttpFoundation\RequestStack $requestStack
32
   *   The request stack service.
33
   */
34
  public function __construct(HttpKernelInterface $httpKernel, RequestStack $requestStack) {
35
    $this->httpKernel = $httpKernel;
36
    $this->requestStack = $requestStack;
37
  }
38
39
  /**
40
   * Add an item to the buffer.
41
   *
42
   * @param \Drupal\Core\Url $url
43
   *   The url object to run the subrequest on.
44
   *
45
   * @return \Closure
46
   *   The callback to invoke to load the result for this buffer item.
47
   */
48
  public function add(Url $url, callable $extract) {
49
    $item = new \ArrayObject([
50
      'url' => $url,
51
      'extract' => $extract,
52
    ]);
53
54
    return $this->createBufferResolver($item);
55
  }
56
57
  /**
58
   * {@inheritdoc}
59
   */
60
  protected function getBufferId($item) {
61
    /** @var \Drupal\Core\Url $url */
62
    $url = $item['url'];
63
    return $url->toString();
64
  }
65
66
  /**
67
   * {@inheritdoc}
68
   */
69
  public function resolveBufferArray(array $buffer) {
70
    /** @var \Drupal\Core\Url $url */
71
    $url = reset($buffer)['url'];
72
    $currentRequest = $this->requestStack->getCurrentRequest();
73
    $request = Request::create(
74
      $url->getOption('routed_path') ?: $url->toString(),
75
      'GET',
76
      $currentRequest->query->all(),
77
      $currentRequest->cookies->all(),
78
      $currentRequest->files->all(),
79
      $currentRequest->server->all()
80
    );
81
82
    $request->attributes->set('_graphql_subrequest', function () use ($buffer) {
83
      return array_map(function ($item) {
84
        return $item['extract']($item['url']);
85
      }, $buffer);
86
    });
87
88
    if ($session = $currentRequest->getSession()) {
89
      $request->setSession($session);
90
    }
91
92
    /** @var \Drupal\graphql\GraphQL\Buffers\SubRequestResponse $response */
93
    $response = $this->httpKernel->handle($request, HttpKernelInterface::SUB_REQUEST);
94
95
    // TODO:
96
    // Remove the request stack manipulation once the core issue described at
97
    // https://www.drupal.org/node/2613044 is resolved.
98
    while ($this->requestStack->getCurrentRequest() === $request) {
99
      $this->requestStack->pop();
100
    }
101
102
    return $response->getResult();
103
  }
104
105
}