Code Duplication    Length = 173-177 lines in 2 locations

src/Plugin/GraphQL/Fields/SubView.php 1 location

@@ 25-201 (lines=177) @@
22
 *   deriver = "Drupal\graphql_views\Plugin\Deriver\Fields\SubViewDeriver"
23
 * )
24
 */
25
class SubView extends FieldPluginBase implements ContainerFactoryPluginInterface {
26
  use DependencySerializationTrait;
27
28
  /**
29
   * The entity type manager.
30
   *
31
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
32
   */
33
  protected $entityTypeManager;
34
35
  /**
36
   * {@inheritdoc}
37
   */
38
  public function __construct(
39
    array $configuration,
40
    $pluginId,
41
    $pluginDefinition,
42
    EntityTypeManagerInterface $entityTypeManager
43
  ) {
44
    $this->entityTypeManager = $entityTypeManager;
45
    parent::__construct($configuration, $pluginId, $pluginDefinition);
46
  }
47
48
  /**
49
   * {@inheritdoc}
50
   */
51
  public static function create(ContainerInterface $container, array $configuration, $pluginId, $pluginDefinition) {
52
    return new static(
53
      $configuration,
54
      $pluginId,
55
      $pluginDefinition,
56
      $container->get('entity_type.manager')
57
    );
58
  }
59
60
  /**
61
   * {@inheritdoc}
62
   */
63
  public function resolveValues($value, array $args, ResolveContext $context, ResolveInfo $info) {
64
    $storage = $this->entityTypeManager->getStorage('view');
65
    $definition = $this->getPluginDefinition();
66
67
    /** @var \Drupal\views\Entity\View $view */
68
    if ($view = $storage->load($definition['view'])) {
69
      $executable = $view->getExecutable();
70
      $executable->setDisplay($definition['display']);
71
      /** @var \Drupal\graphql_views\Plugin\views\display\GraphQL $display */
72
      $display = $executable->getDisplay($definition['display']);
73
74
      // a subview can only work on an entity, so return null it it is not.
75
76
      if (!$value instanceof EntityInterface) {
77
        return;
78
      }
79
80
      // Set the first argument to the id of the current entity.
81
      $executable->setArguments([$value->id()]);
82
83
      $filters = $executable->getDisplay()->getOption('filters');;
84
      $input = $this->extractExposedInput($value, $args, $filters);
85
      $executable->setExposedInput($input);
86
87
      // This is a workaround for the Taxonomy Term filter which requires a full
88
      // exposed form to be sent OR the display being an attachment to just
89
      // accept input values.
90
      $executable->is_attachment = TRUE;
91
      $executable->exposed_raw_input = $input;
92
93
      if (!empty($definition['paged'])) {
94
        // Set paging parameters.
95
        $executable->setItemsPerPage($args['pageSize']);
96
        $executable->setCurrentPage($args['page']);
97
      }
98
99
      if (isset($args['offset']) && !empty($args['offset'])) {
100
        $executable->setOffset($args['offset']);
101
      }
102
103
      $result = $executable->render($definition['display']);
104
      /** @var \Drupal\Core\Cache\CacheableMetadata $cache */
105
      if ($cache = $result['cache']) {
106
        $cache->setCacheContexts(
107
          array_filter($cache->getCacheContexts(), function ($context) {
108
            // Don't emit the url cache contexts.
109
            return $context !== 'url' && strpos($context, 'url.') !== 0;
110
          })
111
        );
112
      }
113
      yield $result;
114
    }
115
  }
116
117
  /**
118
   * {@inheritdoc}
119
   */
120
  protected function getCacheDependencies(array $result, $value, array $args, ResolveContext $context, ResolveInfo $info) {
121
    return array_map(function ($item) {
122
      return $item['cache'];
123
    }, $result);
124
  }
125
126
  /**
127
   * Retrieves the contextual filter argument from the parent value or args.
128
   *
129
   * @param $value
130
   *   The resolved parent value.
131
   * @param $args
132
   *   The arguments provided to the field.
133
   *
134
   * @return array
135
   *   An array of arguments containing the contextual filter value from the
136
   *   parent or provided args if any.
137
   */
138
  protected function extractContextualFilters($value, $args) {
139
    $definition = $this->getPluginDefinition();
140
    $arguments = [];
141
142
    foreach ($definition['arguments_info'] as $argumentId => $argumentInfo) {
143
      if (isset($args['contextualFilter'][$argumentId])) {
144
        $arguments[$argumentInfo['index']] = $args['contextualFilter'][$argumentId];
145
      }
146
      elseif (
147
        $value instanceof EntityInterface &&
148
        $value->getEntityTypeId() === $argumentInfo['entity_type'] &&
149
        (empty($argumentInfo['bundles']) ||
150
          in_array($value->bundle(), $argumentInfo['bundles'], TRUE))
151
      ) {
152
        $arguments[$argumentInfo['index']] = $value->id();
153
      }
154
      else {
155
        $arguments[$argumentInfo['index']] = NULL;
156
      }
157
    }
158
159
    return $arguments;
160
  }
161
162
  /**
163
   * Retrieves sort and filter arguments from the provided field args.
164
   *
165
   * @param $value
166
   *   The resolved parent value.
167
   * @param $args
168
   *   The array of arguments provided to the field.
169
   * @param $filters
170
   *   The available filters for the configured view.
171
   *
172
   * @return array
173
   *   The array of sort and filter arguments to execute the view with.
174
   */
175
  protected function extractExposedInput($value, $args, $filters) {
176
    // Prepare arguments for use as exposed form input.
177
    $input = array_filter([
178
      // Sorting arguments.
179
      'sort_by' => isset($args['sortBy']) ? $args['sortBy'] : NULL,
180
      'sort_order' => isset($args['sortDirection']) ? $args['sortDirection'] : NULL,
181
    ]);
182
183
    // If some filters are missing from the input, set them to an empty string
184
    // explicitly. Otherwise views module generates "Undefined index" notice.
185
    foreach ($filters as $filterKey => $filterRow) {
186
      if (!isset($filterRow['expose']['identifier'])) {
187
        continue;
188
      }
189
190
      $inputKey = $filterRow['expose']['identifier'];
191
      if (!isset($args['filter'][$inputKey])) {
192
        $input[$inputKey] = $filterRow['value'];
193
      } else {
194
        $input[$inputKey] = $args['filter'][$inputKey];
195
      }
196
    }
197
198
    return $input;
199
  }
200
201
}
202

src/Plugin/GraphQL/Fields/View.php 1 location

@@ 25-197 (lines=173) @@
22
 *   deriver = "Drupal\graphql_views\Plugin\Deriver\Fields\ViewDeriver"
23
 * )
24
 */
25
class View extends FieldPluginBase implements ContainerFactoryPluginInterface {
26
  use DependencySerializationTrait;
27
28
  /**
29
   * The entity type manager.
30
   *
31
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
32
   */
33
  protected $entityTypeManager;
34
35
  /**
36
   * {@inheritdoc}
37
   */
38
  public function __construct(
39
    array $configuration,
40
    $pluginId,
41
    $pluginDefinition,
42
    EntityTypeManagerInterface $entityTypeManager
43
  ) {
44
    $this->entityTypeManager = $entityTypeManager;
45
    parent::__construct($configuration, $pluginId, $pluginDefinition);
46
  }
47
48
  /**
49
   * {@inheritdoc}
50
   */
51
  public static function create(ContainerInterface $container, array $configuration, $pluginId, $pluginDefinition) {
52
    return new static(
53
      $configuration,
54
      $pluginId,
55
      $pluginDefinition,
56
      $container->get('entity_type.manager')
57
    );
58
  }
59
60
  /**
61
   * {@inheritdoc}
62
   */
63
  public function resolveValues($value, array $args, ResolveContext $context, ResolveInfo $info) {
64
    $storage = $this->entityTypeManager->getStorage('view');
65
    $definition = $this->getPluginDefinition();
66
67
    /** @var \Drupal\views\Entity\View $view */
68
    if ($view = $storage->load($definition['view'])) {
69
      $executable = $view->getExecutable();
70
      $executable->setDisplay($definition['display']);
71
72
      // Set view contextual filters.
73
      /* @see \Drupal\graphql_views\ViewDeriverHelperTrait::getArgumentsInfo() */
74
      if (!empty($definition['arguments_info'])) {
75
        $arguments = $this->extractContextualFilters($value, $args);
76
        $executable->setArguments($arguments);
77
      }
78
79
      $filters = $executable->getDisplay()->getOption('filters');;
80
      $input = $this->extractExposedInput($value, $args, $filters);
81
      $executable->setExposedInput($input);
82
83
      // This is a workaround for the Taxonomy Term filter which requires a full
84
      // exposed form to be sent OR the display being an attachment to just
85
      // accept input values.
86
      $executable->is_attachment = TRUE;
87
      $executable->exposed_raw_input = $input;
88
89
      if (!empty($definition['paged'])) {
90
        // Set paging parameters.
91
        $executable->setItemsPerPage($args['pageSize']);
92
        $executable->setCurrentPage($args['page']);
93
      }
94
95
      if (isset($args['offset']) && !empty($args['offset'])) {
96
        $executable->setOffset($args['offset']);
97
      }
98
99
      $result = $executable->render($definition['display']);
100
      /** @var \Drupal\Core\Cache\CacheableMetadata $cache */
101
      if ($cache = $result['cache']) {
102
        $cache->setCacheContexts(
103
          array_filter($cache->getCacheContexts(), function ($context) {
104
            // Don't emit the url cache contexts.
105
            return $context !== 'url' && strpos($context, 'url.') !== 0;
106
          })
107
        );
108
      }
109
      yield $result;
110
    }
111
  }
112
113
  /**
114
   * {@inheritdoc}
115
   */
116
  protected function getCacheDependencies(array $result, $value, array $args, ResolveContext $context, ResolveInfo $info) {
117
    return array_map(function ($item) {
118
      return $item['cache'];
119
    }, $result);
120
  }
121
122
  /**
123
   * Retrieves the contextual filter argument from the parent value or args.
124
   *
125
   * @param $value
126
   *   The resolved parent value.
127
   * @param $args
128
   *   The arguments provided to the field.
129
   *
130
   * @return array
131
   *   An array of arguments containing the contextual filter value from the
132
   *   parent or provided args if any.
133
   */
134
  protected function extractContextualFilters($value, $args) {
135
    $definition = $this->getPluginDefinition();
136
    $arguments = [];
137
138
    foreach ($definition['arguments_info'] as $argumentId => $argumentInfo) {
139
      if (isset($args['contextualFilter'][$argumentId])) {
140
        $arguments[$argumentInfo['index']] = $args['contextualFilter'][$argumentId];
141
      }
142
      elseif (
143
        $value instanceof EntityInterface &&
144
        $value->getEntityTypeId() === $argumentInfo['entity_type'] &&
145
        (empty($argumentInfo['bundles']) ||
146
          in_array($value->bundle(), $argumentInfo['bundles'], TRUE))
147
      ) {
148
        $arguments[$argumentInfo['index']] = $value->id();
149
      }
150
      else {
151
        $arguments[$argumentInfo['index']] = NULL;
152
      }
153
    }
154
155
    return $arguments;
156
  }
157
158
  /**
159
   * Retrieves sort and filter arguments from the provided field args.
160
   *
161
   * @param $value
162
   *   The resolved parent value.
163
   * @param $args
164
   *   The array of arguments provided to the field.
165
   * @param $filters
166
   *   The available filters for the configured view.
167
   *
168
   * @return array
169
   *   The array of sort and filter arguments to execute the view with.
170
   */
171
  protected function extractExposedInput($value, $args, $filters) {
172
    // Prepare arguments for use as exposed form input.
173
    $input = array_filter([
174
      // Sorting arguments.
175
      'sort_by' => isset($args['sortBy']) ? $args['sortBy'] : NULL,
176
      'sort_order' => isset($args['sortDirection']) ? $args['sortDirection'] : NULL,
177
    ]);
178
179
    // If some filters are missing from the input, set them to an empty string
180
    // explicitly. Otherwise views module generates "Undefined index" notice.
181
    foreach ($filters as $filterKey => $filterRow) {
182
      if (!isset($filterRow['expose']['identifier'])) {
183
        continue;
184
      }
185
186
      $inputKey = $filterRow['expose']['identifier'];
187
      if (!isset($args['filter'][$inputKey])) {
188
        $input[$inputKey] = $filterRow['value'];
189
      } else {
190
        $input[$inputKey] = $args['filter'][$inputKey];
191
      }
192
    }
193
194
    return $input;
195
  }
196
197
}
198