Completed
Push — 8.x-3.x ( 32ff4d...d01c55 )
by Sebastian
05:23 queued 02:25
created

View::getCacheDependencies()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 3
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Drupal\graphql_core\Plugin\GraphQL\Fields\Views;
4
5
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
6
use Drupal\Core\Entity\EntityInterface;
7
use Drupal\Core\Entity\EntityTypeManagerInterface;
8
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
9
use Drupal\graphql\Plugin\GraphQL\Fields\FieldPluginBase;
10
use Symfony\Component\DependencyInjection\ContainerInterface;
11
use Youshido\GraphQL\Execution\ResolveInfo;
12
13
/**
14
 * Expose views as root fields.
15
 *
16
 * @GraphQLField(
17
 *   id = "view",
18
 *   secure = true,
19
 *   nullable = true,
20
 *   multi = true,
21
 *   parents = {"Root"},
22
 *   provider = "views",
23
 *   deriver = "Drupal\graphql_core\Plugin\Deriver\Fields\ViewDeriver"
24
 * )
25
 */
26
class View extends FieldPluginBase implements ContainerFactoryPluginInterface {
27
  use DependencySerializationTrait;
28
29
  /**
30
   * The entity type manager.
31
   *
32
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
33
   */
34
  protected $entityTypeManager;
35
36
  /**
37
   * {@inheritdoc}
38
   */
39
  public function __construct(
40
    array $configuration,
41
    $pluginId,
42
    $pluginDefinition,
43
    EntityTypeManagerInterface $entityTypeManager
44
  ) {
45
    $this->entityTypeManager = $entityTypeManager;
46
    parent::__construct($configuration, $pluginId, $pluginDefinition);
47
  }
48
49
  /**
50
   * {@inheritdoc}
51
   */
52
  public static function create(ContainerInterface $container, array $configuration, $pluginId, $pluginDefinition) {
53
    return new static(
54
      $configuration,
55
      $pluginId,
56
      $pluginDefinition,
57
      $container->get('entity_type.manager')
58
    );
59
  }
60
61
  /**
62
   * {@inheritdoc}
63
   */
64
  public function resolveValues($value, array $args, ResolveInfo $info) {
65
    $storage = $this->entityTypeManager->getStorage('view');
66
    $definition = $this->getPluginDefinition();
67
68
    /** @var \Drupal\views\Entity\View $view */
69
    if ($view = $storage->load($definition['view'])) {
70
      $executable = $view->getExecutable();
71
      $executable->setDisplay($definition['display']);
72
73
      // Set view contextual filters.
74
      /* @see \Drupal\graphql_core\Plugin\Deriver\ViewDeriverBase::getArgumentsInfo() */
0 ignored issues
show
Unused Code Comprehensibility introduced by
38% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
75
      if (!empty($definition['arguments_info'])) {
76
        $arguments = $this->extractContextualFilters($value, $args);
77
        $executable->setArguments($arguments);
78
      }
79
80
      $filters = $executable->getDisplay()->getOption('filters');;
81
      $input = $this->extractExposedInput($value, $args, $filters);
82
      $executable->setExposedInput($input);
83
84
      // This is a workaround for the Taxonomy Term filter which requires a full
85
      // exposed form to be sent OR the display being an attachment to just
86
      // accept input values.
87
      $executable->is_attachment = TRUE;
88
      $executable->exposed_raw_input = $input;
89
90
      if (!empty($definition['paged'])) {
91
        // Set paging parameters.
92
        $executable->setItemsPerPage($args['pageSize']);
93
        $executable->setCurrentPage($args['page']);
94
      }
95
96
      yield $executable->render($definition['display']);
97
    }
98
  }
99
100
  /**
101
   * {@inheritdoc}
102
   */
103
  protected function getCacheDependencies($result, $value, array $args) {
104
    $result = reset($result);
105
    return [$result['cache']];
106
  }
107
108
  /**
109
   * Retrieves the contextual filter argument from the parent value or args.
110
   *
111
   * @param $value
112
   *   The resolved parent value.
113
   * @param $args
114
   *   The arguments provided to the field.
115
   *
116
   * @return array
117
   *   An array of arguments containing the contextual filter value from the
118
   *   parent or provided args if any.
119
   */
120
  protected function extractContextualFilters($value, $args) {
121
    $definition = $this->getPluginDefinition();
122
    $arguments = [];
123
124
    foreach ($definition['arguments_info'] as $argumentId => $argumentInfo) {
125
      if (isset($args['contextualFilter'][$argumentId])) {
126
        $arguments[$argumentInfo['index']] = $args['contextualFilter'][$argumentId];
127
      }
128
      elseif (
129
        $value instanceof EntityInterface &&
0 ignored issues
show
Bug introduced by
The class Drupal\Core\Entity\EntityInterface does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
130
        $value->getEntityTypeId() === $argumentInfo['entity_type'] &&
131
        (empty($argumentInfo['bundles']) ||
132
          in_array($value->bundle(), $argumentInfo['bundles'], TRUE))
133
      ) {
134
        $arguments[$argumentInfo['index']] = $value->id();
135
      }
136
      else {
137
        $arguments[$argumentInfo['index']] = NULL;
138
      }
139
    }
140
141
    return $arguments;
142
  }
143
144
  /**
145
   * Retrieves sort and filter arguments from the provided field args.
146
   *
147
   * @param $value
148
   *   The resolved parent value.
149
   * @param $args
150
   *   The array of arguments provided to the field.
151
   * @param $filters
152
   *   The available filters for the configured view.
153
   *
154
   * @return array
155
   *   The array of sort and filter arguments to execute the view with.
156
   */
157
  protected function extractExposedInput($value, $args, $filters) {
158
    // Prepare arguments for use as exposed form input.
159
    $input = array_filter([
160
      // Sorting arguments.
161
      'sort_by' => isset($args['sortBy']) ? $args['sortBy'] : NULL,
162
      'sort_order' => isset($args['sortDirection']) ? $args['sortDirection'] : NULL,
163
    ]);
164
165
    // If some filters are missing from the input, set them to an empty string
166
    // explicitly. Otherwise views module generates "Undefined index" notice.
167
    foreach ($filters as $filterKey => $filterRow) {
168
      if (!isset($filterRow['expose']['identifier'])) {
169
        continue;
170
      }
171
172
      $inputKey = $filterRow['expose']['identifier'];
173
      if (!isset($args['filter'][$inputKey])) {
174
        $input[$inputKey] = $filterRow['value'];
175
      } else {
176
        $input[$inputKey] = $args['filter'][$inputKey];
177
      }
178
    }
179
180
    return $input;
181
  }
182
183
}
184