@@ 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 |
@@ 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 |