Completed
Push — 8.x-3.x ( 885c5d...d5d047 )
by Sebastian
02:33
created

QueryCacheContext::getContext()   D

Complexity

Conditions 10
Paths 5

Size

Total Lines 29
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 20
nc 5
nop 0
dl 0
loc 29
rs 4.8196
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Drupal\graphql\Cache\Context;
4
5
use Drupal\Core\Cache\CacheableMetadata;
6
use Drupal\Core\Cache\Context\CacheContextInterface;
7
use Symfony\Component\HttpFoundation\RequestStack;
8
9
/**
10
 * Defines the QueryCacheContext service, for "per query" caching.
11
 *
12
 * Cache context ID: 'gql'.
13
 */
14
class QueryCacheContext implements CacheContextInterface {
15
16
  /**
17
   * The request stack.
18
   *
19
   * @var \Symfony\Component\HttpFoundation\RequestStack
20
   */
21
  protected $requestStack;
22
23
  /**
24
   * Static cache of hashed cache contexts.
25
   *
26
   * @var \SplObjectStorage
27
   */
28
  protected $contextCache;
29
30
  /**
31
   * Constructs a new QueryCacheContext class.
32
   *
33
   * @param \Symfony\Component\HttpFoundation\RequestStack $requestStack
34
   *   The request stack.
35
   */
36
  public function __construct(RequestStack $requestStack) {
37
    $this->requestStack = $requestStack;
38
    $this->contextCache = new \SplObjectStorage();
39
  }
40
41
  /**
42
   * {@inheritdoc}
43
   */
44
  public static function getLabel() {
45
    return t('Query');
46
  }
47
48
  /**
49
   * {@inheritdoc}
50
   */
51
  public function getContext() {
52
    $request = $this->requestStack->getCurrentRequest();
53
    if (isset($this->contextCache[$request])) {
54
      return $this->contextCache[$request];
55
    }
56
57
    $hash = '';
58
    if ($request->attributes->has('query')) {
59
      $hash = $this->contextCache[$request] = $this->getHash(
60
        $request->attributes->get('schema') ?: '',
61
        $request->attributes->get('query') ?: '',
62
        $request->attributes->get('variables') ?: []
63
      );
64
    }
65
    else if ($request->attributes->has('queries')) {
66
      $queries = $request->attributes->get('queries');
67
      $schema = $request->attributes->get('schema') ?: '';
68
69
      return hash('sha256', json_encode(array_map(function($item) use ($schema) {
70
        return $this->getHash(
71
          $schema,
72
          !empty($item['query']) ? $item['query'] : '',
73
          !empty($item['variables']) ? $item['variables'] : []
74
        );
75
      }, $queries)));
76
    }
77
78
    return $this->contextCache[$request] = $hash;
79
  }
80
81
  /**
82
   * Produces an optimized hashed string of the query and variables.
83
   *
84
   * Sorts the variables by their key and eliminates whitespace from the query
85
   * to enable better reuse of the cache entries.
86
   *
87
   * @param string $schema
88
   *   The schema id.
89
   * @param string $query
90
   *   The graphql query string.
91
   * @param array $variables
92
   *   The graphql query variables.
93
   *
94
   * @return string
95
   *   The hashed string containing.
96
   */
97
  protected function getHash($schema = '', $query = '', array $variables = []) {
98
    $query = preg_replace('/\s{2,}/', ' ', $query);
99
    ksort($variables);
100
101
    return hash('sha256', json_encode([
102
      'schema' => $schema,
103
      'query' => $query,
104
      'variables' => $variables,
105
    ]));
106
  }
107
108
  /**
109
   * {@inheritdoc}
110
   */
111
  public function getCacheableMetadata() {
112
    return new CacheableMetadata();
113
  }
114
115
}
116