Passed
Pull Request — 8.x-1.x (#40)
by
unknown
02:16
created

Views::resolve()   B

Complexity

Conditions 7
Paths 32

Size

Total Lines 54
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 28
c 1
b 0
f 0
nc 32
nop 9
dl 0
loc 54
rs 8.5386

How to fix   Long Method    Many Parameters   

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:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
namespace Drupal\graphql_views\Plugin\GraphQL\DataProducer;
4
5
use Drupal\Component\Utility\NestedArray;
0 ignored issues
show
Bug introduced by
The type Drupal\Component\Utility\NestedArray was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
use Drupal\Core\Entity\EntityTypeManagerInterface;
0 ignored issues
show
Bug introduced by
The type Drupal\Core\Entity\EntityTypeManagerInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
7
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
0 ignored issues
show
Bug introduced by
The type Drupal\Core\Plugin\ContainerFactoryPluginInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
8
use Drupal\graphql\GraphQL\Execution\FieldContext;
0 ignored issues
show
Bug introduced by
The type Drupal\graphql\GraphQL\Execution\FieldContext was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
9
use Drupal\graphql\Plugin\GraphQL\DataProducer\DataProducerPluginBase;
0 ignored issues
show
Bug introduced by
The type Drupal\graphql\Plugin\Gr...\DataProducerPluginBase was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
10
use Drupal\views\Plugin\views\display\DisplayPluginInterface;
0 ignored issues
show
Bug introduced by
The type Drupal\views\Plugin\view...\DisplayPluginInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
11
use Symfony\Component\DependencyInjection\ContainerInterface;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\Depend...tion\ContainerInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
12
13
/**
14
 * GraphQL data producer for views.
15
 *
16
 * @DataProducer(
17
 *   id = "views",
18
 *   name = @Translation("Views"),
19
 *   description = @Translation("Views."),
20
 *   produces = @ContextDefinition("entity",
21
 *     label = @Translation("Entity")
22
 *   ),
23
 *   consumes = {
24
 *     "view_id" = @ContextDefinition("string",
25
 *       label = @Translation("View ID")
26
 *     ),
27
 *     "display_id" = @ContextDefinition("string",
28
 *       label = @Translation("Display ID")
29
 *     ),
30
 *     "offset" = @ContextDefinition("integer",
31
 *       label = @Translation("Offset"),
32
 *       required = FALSE
33
 *     ),
34
 *     "page_size" = @ContextDefinition("integer",
35
 *       label = @Translation("Page size"),
36
 *       required = FALSE
37
 *     ),
38
 *     "page" = @ContextDefinition("integer",
39
 *       label = @Translation("Current page"),
40
 *       required = FALSE
41
 *     ),
42
 *     "sort_by" = @ContextDefinition("string",
43
 *       label = @Translation("Sort by"),
44
 *       required = FALSE
45
 *     ),
46
 *     "sort_direction" = @ContextDefinition("string",
47
 *       label = @Translation("Sort direction"),
48
 *       required = FALSE
49
 *     ),
50
 *     "filter" = @ContextDefinition("any",
51
 *       label = @Translation("Sort direction"),
52
 *       required = FALSE,
53
 *       default_value = {}
54
 *     )
55
 *   }
56
 * )
57
 */
58
class Views extends DataProducerPluginBase implements ContainerFactoryPluginInterface {
59
60
  /**
61
   * The entity type manager.
62
   *
63
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
64
   */
65
  protected $entityTypeManager;
66
67
  /**
68
   * {@inheritdoc}
69
   */
70
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
71
    return new static($configuration, $plugin_id, $plugin_definition, $container->get('entity_type.manager'));
72
  }
73
74
  /**
75
   * {@inheritdoc}
76
   */
77
  public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entityTypeManager) {
78
    parent::__construct($configuration, $plugin_id, $plugin_definition);
79
    $this->entityTypeManager = $entityTypeManager;
80
  }
81
82
  /**
83
   * Resolve the data.
84
   *
85
   * @param string $view_id
86
   *   The view ID.
87
   * @param string $display_id
88
   *   The display ID.
89
   * @param int|null $offset
90
   *   Offset of the query.
91
   * @param int|null $page_size
92
   *   Number of items on page.
93
   * @param int|null $page
94
   *   Number of page.
95
   *
96
   * @return array|null
97
   *   List of entities.
98
   *
99
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
100
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
101
   */
102
  public function resolve(string $view_id, string $display_id, int $offset = NULL, int $page_size = NULL, int $page = NULL, string $sort_by = NULL, string $sort_direction = NULL, array $filter = [], FieldContext $fieldContext) {
103
104
    /** @var \Drupal\views\Entity\View $view */
105
    $view = \Drupal::entityTypeManager()->getStorage('view')->load($view_id);
106
107
    $executable = $view->getExecutable();
108
    $executable->setDisplay($display_id);
109
110
    // Set paging parameters.
111
    if (empty($page_size)) {
112
      $page_size = $this->getPagerLimit($executable->getDisplay());
113
    }
114
    if (empty($page)) {
115
      $page = $this->getPagerOffset($executable->getDisplay());
116
    }
117
    if ($this->isPaged($executable->getDisplay())) {
118
      $executable->setItemsPerPage($page_size);
119
      $executable->setCurrentPage($page);
120
    }
121
122
    if ($offset) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $offset of type integer|null is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
123
      $executable->setOffset($offset);
124
    }
125
126
    $available_filters = $executable->getDisplay()->getOption('filters');
127
    $input = $this->extractExposedInput($sort_by, $sort_direction, $filter, $available_filters);
128
    $executable->setExposedInput($input);
129
130
    // This is a workaround for the Taxonomy Term filter which requires a full
131
    // exposed form to be sent OR the display being an attachment to just
132
    // accept input values.
133
    $executable->is_attachment = TRUE;
134
    $executable->exposed_raw_input = $input;
135
136
    $executable->preExecute();
137
    $executable->execute();
138
139
    $result = $executable->render($display_id);
140
141
142
    /** @var \Drupal\Core\Cache\CacheableMetadata $cache */
143
    if ($cache = $result['cache']) {
144
      $cache->setCacheContexts(
145
        array_filter($cache->getCacheContexts(), function ($context) {
146
          // Don't emit the url cache contexts.
147
          return $context !== 'url' && strpos($context, 'url.') !== 0;
148
        })
149
      );
150
      $fieldContext->addCacheableDependency($cache);
151
    }
152
153
    return [
154
      'results' => $result['rows'],
155
      'count' => $result['view']->total_rows,
156
    ];
157
  }
158
159
  /**
160
   * Check if a pager is configured.
161
   *
162
   * @param \Drupal\views\Plugin\views\display\DisplayPluginInterface $display
163
   *   The display configuration.
164
   *
165
   * @return bool
166
   *   Flag indicating if the view is configured with a pager.
167
   */
168
  protected function isPaged(DisplayPluginInterface $display) {
169
    $pagerOptions = $display->getOption('pager');
170
    return isset($pagerOptions['type']) && in_array($pagerOptions['type'], [
171
      'full',
172
      'mini',
173
    ]);
174
  }
175
176
  /**
177
   * Get the configured default limit.
178
   *
179
   * @param \Drupal\views\Plugin\views\display\DisplayPluginInterface $display
180
   *   The display configuration.
181
   *
182
   * @return int
183
   *   The default limit.
184
   */
185
  protected function getPagerLimit(DisplayPluginInterface $display) {
186
    $pagerOptions = $display->getOption('pager');
187
    return NestedArray::getValue($pagerOptions, [
188
      'options',
189
      'items_per_page',
190
    ]) ?: 0;
191
  }
192
193
  /**
194
   * Get the configured default offset.
195
   *
196
   * @param \Drupal\views\Plugin\views\display\DisplayPluginInterface $display
197
   *   The display configuration.
198
   *
199
   * @return int
200
   *   The default offset.
201
   */
202
  protected function getPagerOffset(DisplayPluginInterface $display) {
203
    $pagerOptions = $display->getOption('pager');
204
    return NestedArray::getValue($pagerOptions, [
205
      'options',
206
      'offset',
207
    ]) ?: 0;
208
  }
209
210
  /**
211
   * Retrieves sort and filter arguments from the provided field args.
212
   *
213
   * @param $value
214
   *   The resolved parent value.
215
   * @param $args
216
   *   The array of arguments provided to the field.
217
   * @param $available_filters
218
   *   The available filters for the configured view.
219
   *
220
   * @return array
221
   *   The array of sort and filter arguments to execute the view with.
222
   */
223
  protected function extractExposedInput($sort_by, $sort_direction, $filter, $available_filters) {
224
    // Prepare arguments for use as exposed form input.
225
    $input = array_filter([
226
      // Sorting arguments.
227
      'sort_by' => $sort_by,
228
      'sort_order' => $sort_direction,
229
    ]);
230
231
    // If some filters are missing from the input, set them to an empty string
232
    // explicitly. Otherwise views module generates "Undefined index" notice.
233
    foreach ($available_filters as $filterRow) {
234
      if (!isset($filterRow['expose']['identifier'])) {
235
        continue;
236
      }
237
238
      $inputKey = $filterRow['expose']['identifier'];
239
      if (!isset($filter[$inputKey])) {
240
        $input[$inputKey] = $filterRow['value'];
241
      } else {
242
        $input[$inputKey] = $filter[$inputKey];
243
      }
244
    }
245
    return $input;
246
  }
247
248
}
249