Chris@5
|
1 <?php
|
Chris@5
|
2
|
Chris@5
|
3 namespace Drupal\views_slideshow\Plugin\views\style;
|
Chris@5
|
4
|
Chris@5
|
5 use Drupal\Core\Form\FormStateInterface;
|
Chris@5
|
6 use Drupal\views\Plugin\views\style\StylePluginBase;
|
Chris@5
|
7 use Drupal\Core\Url;
|
Chris@5
|
8 use Drupal\Core\Link;
|
Chris@5
|
9
|
Chris@5
|
10 /**
|
Chris@5
|
11 * Style plugin to render each item in a slideshow.
|
Chris@5
|
12 *
|
Chris@5
|
13 * @ingroup views_style_plugins
|
Chris@5
|
14 *
|
Chris@5
|
15 * @ViewsStyle(
|
Chris@5
|
16 * id = "slideshow",
|
Chris@5
|
17 * title = @Translation("Slideshow"),
|
Chris@5
|
18 * help = @Translation("Display the results as a slideshow."),
|
Chris@5
|
19 * theme = "views_view_slideshow",
|
Chris@5
|
20 * display_types = {"normal"}
|
Chris@5
|
21 * )
|
Chris@5
|
22 */
|
Chris@5
|
23 class Slideshow extends StylePluginBase {
|
Chris@5
|
24
|
Chris@5
|
25 /**
|
Chris@5
|
26 * Does the style plugin allows to use style plugins.
|
Chris@5
|
27 *
|
Chris@5
|
28 * @var bool
|
Chris@5
|
29 */
|
Chris@5
|
30 protected $usesRowPlugin = TRUE;
|
Chris@5
|
31
|
Chris@5
|
32 /**
|
Chris@5
|
33 * Does the style plugin support custom css class for the rows.
|
Chris@5
|
34 *
|
Chris@5
|
35 * @var bool
|
Chris@5
|
36 */
|
Chris@5
|
37 protected $usesRowClass = TRUE;
|
Chris@5
|
38
|
Chris@5
|
39 /**
|
Chris@5
|
40 * Does the style plugin support grouping of rows.
|
Chris@5
|
41 *
|
Chris@5
|
42 * @var bool
|
Chris@5
|
43 */
|
Chris@5
|
44 protected $usesGrouping = FALSE;
|
Chris@5
|
45
|
Chris@5
|
46 /**
|
Chris@5
|
47 * Does the style plugin for itself support to add fields to it's output.
|
Chris@5
|
48 *
|
Chris@5
|
49 * This option only makes sense on style plugins without row plugins, like
|
Chris@5
|
50 * for example table.
|
Chris@5
|
51 *
|
Chris@5
|
52 * @var bool
|
Chris@5
|
53 */
|
Chris@5
|
54 protected $usesFields = TRUE;
|
Chris@5
|
55
|
Chris@5
|
56 /**
|
Chris@5
|
57 * {@inheritdoc}
|
Chris@5
|
58 */
|
Chris@5
|
59 protected function defineOptions() {
|
Chris@5
|
60 $options = parent::defineOptions();
|
Chris@5
|
61 $options['row_class_custom'] = ['default' => ''];
|
Chris@5
|
62 $options['row_class_default'] = ['default' => TRUE];
|
Chris@5
|
63 $options['slideshow_type'] = ['default' => 'views_slideshow_cycle'];
|
Chris@5
|
64 $options['slideshow_skin'] = ['default' => 'default'];
|
Chris@5
|
65
|
Chris@5
|
66 $typeManager = \Drupal::service('plugin.manager.views_slideshow.slideshow_type');
|
Chris@5
|
67 foreach ($typeManager->getDefinitions() as $id => $definition) {
|
Chris@5
|
68 $instance = $typeManager->createInstance($id, []);
|
Chris@5
|
69 $options[$id] = $instance->defaultConfiguration();
|
Chris@5
|
70 }
|
Chris@5
|
71
|
Chris@5
|
72 $widgetTypeManager = \Drupal::service('plugin.manager.views_slideshow.widget_type');
|
Chris@5
|
73 $widgetTypes = $widgetTypeManager->getDefinitions();
|
Chris@5
|
74 foreach (['top', 'bottom'] as $location) {
|
Chris@5
|
75 foreach ($widgetTypes as $widgetTypeId => $widgetTypeDefinition) {
|
Chris@5
|
76 $options['widgets']['contains'][$location]['contains'][$widgetTypeId]['contains'] = $widgetTypeManager->createInstance($widgetTypeId, [])->defaultConfiguration();
|
Chris@5
|
77 }
|
Chris@5
|
78 }
|
Chris@5
|
79
|
Chris@5
|
80 return $options;
|
Chris@5
|
81 }
|
Chris@5
|
82
|
Chris@5
|
83 /**
|
Chris@5
|
84 * {@inheritdoc}
|
Chris@5
|
85 */
|
Chris@5
|
86 public function buildOptionsForm(&$form, FormStateInterface $form_state) {
|
Chris@5
|
87 parent::buildOptionsForm($form, $form_state);
|
Chris@5
|
88
|
Chris@5
|
89 // Wrap all the form elements to help style the form.
|
Chris@5
|
90 $form['views_slideshow_wrapper'] = [
|
Chris@5
|
91 '#markup' => '<div id="views-slideshow-form-wrapper">',
|
Chris@5
|
92 ];
|
Chris@5
|
93
|
Chris@5
|
94 // Skins.
|
Chris@5
|
95 $form['slideshow_skin_header'] = [
|
Chris@5
|
96 '#markup' => '<h2>' . $this->t('Style') . '</h2>',
|
Chris@5
|
97 ];
|
Chris@5
|
98
|
Chris@5
|
99 /* @var \Drupal\Component\Plugin\PluginManagerInterface */
|
Chris@5
|
100 $skinManager = \Drupal::service('plugin.manager.views_slideshow.slideshow_skin');
|
Chris@5
|
101
|
Chris@5
|
102 // Get all skins to create the option list.
|
Chris@5
|
103 $skins = [];
|
Chris@5
|
104 foreach ($skinManager->getDefinitions() as $id => $definition) {
|
Chris@5
|
105 $skins[$id] = $definition['label'];
|
Chris@5
|
106 }
|
Chris@5
|
107 asort($skins);
|
Chris@5
|
108
|
Chris@5
|
109 // Create the drop down box so users can choose an available skin.
|
Chris@5
|
110 $form['slideshow_skin'] = [
|
Chris@5
|
111 '#type' => 'select',
|
Chris@5
|
112 '#title' => $this->t('Skin'),
|
Chris@5
|
113 '#options' => $skins,
|
Chris@5
|
114 '#default_value' => $this->options['slideshow_skin'],
|
Chris@5
|
115 '#description' => $this->t('Select the skin to use for this display. Skins allow for easily swappable layouts of things like next/prev links and thumbnails. Note that not all skins support all widgets, so a combination of skins and widgets may lead to unpredictable results in layout.'),
|
Chris@5
|
116 ];
|
Chris@5
|
117
|
Chris@5
|
118 // Slides.
|
Chris@5
|
119 $form['slides_header'] = [
|
Chris@5
|
120 '#markup' => '<h2>' . $this->t('Slides') . '</h2>',
|
Chris@5
|
121 ];
|
Chris@5
|
122
|
Chris@5
|
123 // Get all slideshow types.
|
Chris@5
|
124 $typeManager = \Drupal::service('plugin.manager.views_slideshow.slideshow_type');
|
Chris@5
|
125 $types = $typeManager->getDefinitions();
|
Chris@5
|
126
|
Chris@5
|
127 if ($types) {
|
Chris@5
|
128
|
Chris@5
|
129 // Build our slideshow options for the form.
|
Chris@5
|
130 $slideshow_options = [];
|
Chris@5
|
131 foreach ($types as $id => $definition) {
|
Chris@5
|
132 $slideshow_options[$id] = $definition['label'];
|
Chris@5
|
133 }
|
Chris@5
|
134
|
Chris@5
|
135 $form['slideshow_type'] = [
|
Chris@5
|
136 '#type' => 'select',
|
Chris@5
|
137 '#title' => $this->t('Slideshow Type'),
|
Chris@5
|
138 '#options' => $slideshow_options,
|
Chris@5
|
139 '#default_value' => $this->options['slideshow_type'],
|
Chris@5
|
140 ];
|
Chris@5
|
141
|
Chris@5
|
142 // @todo: check if default values are properly passed to the buildConfigurationForm().
|
Chris@5
|
143 foreach ($types as $id => $definition) {
|
Chris@5
|
144 $configuration = [];
|
Chris@5
|
145 if (!empty($this->options[$id])) {
|
Chris@5
|
146 $configuration = $this->options[$id];
|
Chris@5
|
147 }
|
Chris@5
|
148 $instance = $typeManager->createInstance($id, $configuration);
|
Chris@5
|
149
|
Chris@5
|
150 $form[$id] = [
|
Chris@5
|
151 '#type' => 'fieldset',
|
Chris@5
|
152 '#title' => $this->t('@module options', ['@module' => $definition['label']]),
|
Chris@5
|
153 '#collapsible' => TRUE,
|
Chris@5
|
154 '#attributes' => ['class' => [$id]],
|
Chris@5
|
155 '#states' => [
|
Chris@5
|
156 'visible' => [
|
Chris@5
|
157 ':input[name="style_options[slideshow_type]"]' => ['value' => $id],
|
Chris@5
|
158 ],
|
Chris@5
|
159 ],
|
Chris@5
|
160 ];
|
Chris@5
|
161
|
Chris@5
|
162 $form = $instance->buildConfigurationForm($form, $form_state);
|
Chris@5
|
163 }
|
Chris@5
|
164 }
|
Chris@5
|
165 else {
|
Chris@5
|
166 $form['enable_module'] = [
|
Chris@5
|
167 '#markup' => $this->t('There is no Views Slideshow plugin enabled. Go to the @modules and enable a Views Slideshow plugin module. For example Views Slideshow Cycle.', ['@modules' => Link::fromTextAndUrl($this->t('Modules Page'), Url::fromRoute('system.modules_list'))->toString()]),
|
Chris@5
|
168 ];
|
Chris@5
|
169 }
|
Chris@5
|
170
|
Chris@5
|
171 // Widgets.
|
Chris@5
|
172 // @todo: Improve the UX by using Ajax.
|
Chris@5
|
173 $form['widgets_header'] = [
|
Chris@5
|
174 '#markup' => '<h2>' . $this->t('Widgets') . '</h2>',
|
Chris@5
|
175 ];
|
Chris@5
|
176
|
Chris@5
|
177 // Define the available locations.
|
Chris@5
|
178 $location = ['top' => $this->t('Top'), 'bottom' => $this->t('Bottom')];
|
Chris@5
|
179
|
Chris@5
|
180 // Loop through all locations so we can add header for each location.
|
Chris@5
|
181 foreach ($location as $location_id => $location_name) {
|
Chris@5
|
182 $form['widgets'][$location_id]['header'] = [
|
Chris@5
|
183 '#markup' => '<h3>' . $this->t('@location Widgets', ['@location' => $location_name]) . '</h3>',
|
Chris@5
|
184 ];
|
Chris@5
|
185 }
|
Chris@5
|
186
|
Chris@5
|
187 /* @var \Drupal\Component\Plugin\PluginManagerInterface */
|
Chris@5
|
188 $widgetTypeManager = \Drupal::service('plugin.manager.views_slideshow.widget_type');
|
Chris@5
|
189
|
Chris@5
|
190 // Get all widgets types that are registered.
|
Chris@5
|
191 $widgets = $widgetTypeManager->getDefinitions();
|
Chris@5
|
192 if (!empty($widgets)) {
|
Chris@5
|
193
|
Chris@5
|
194 // Build our weight values by number of widgets.
|
Chris@5
|
195 $weights = [];
|
Chris@5
|
196 for ($i = 1; $i <= count($widgets); $i++) {
|
Chris@5
|
197 $weights[$i] = $i;
|
Chris@5
|
198 }
|
Chris@5
|
199
|
Chris@5
|
200 // Loop through our widgets and locations to build our form values for
|
Chris@5
|
201 // each widget.
|
Chris@5
|
202 foreach ($widgets as $widget_id => $widget_info) {
|
Chris@5
|
203
|
Chris@5
|
204 // Determine if this widget type is compatible with any slideshow type.
|
Chris@5
|
205 $compatible_slideshows = [];
|
Chris@5
|
206 foreach ($types as $slideshow_id => $slideshow_info) {
|
Chris@5
|
207 if ($widgetTypeManager->createInstance($widget_id, [])->checkCompatiblity($slideshow_info)) {
|
Chris@5
|
208 $compatible_slideshows[] = $slideshow_id;
|
Chris@5
|
209 }
|
Chris@5
|
210 }
|
Chris@5
|
211
|
Chris@5
|
212 // Display the widget config form only if the widget type is compatible
|
Chris@5
|
213 // with at least one slideshow type.
|
Chris@5
|
214 if (!empty($compatible_slideshows)) {
|
Chris@5
|
215 foreach ($location as $location_id => $location_name) {
|
Chris@5
|
216 // Use Widget Checkbox.
|
Chris@5
|
217 $form['widgets'][$location_id][$widget_id]['enable'] = [
|
Chris@5
|
218 '#type' => 'checkbox',
|
Chris@5
|
219 '#title' => $widget_info['label'],
|
Chris@5
|
220 '#default_value' => $this->options['widgets'][$location_id][$widget_id]['enable'],
|
Chris@5
|
221 '#description' => $this->t('Should @name be rendered at the @location of the slides.', ['@name' => $widget_info['label'], '@location' => $location_name]),
|
Chris@5
|
222 '#dependency' => [
|
Chris@5
|
223 'edit-style-options-slideshow-type' => $compatible_slideshows,
|
Chris@5
|
224 ],
|
Chris@5
|
225 ];
|
Chris@5
|
226
|
Chris@5
|
227 // Need to wrap this so it indents correctly.
|
Chris@5
|
228 $form['widgets'][$location_id][$widget_id]['wrapper'] = [
|
Chris@5
|
229 '#markup' => '<div class="vs-dependent">',
|
Chris@5
|
230 ];
|
Chris@5
|
231
|
Chris@5
|
232 // Widget weight.
|
Chris@5
|
233 // We check to see if the default value is greater than the number
|
Chris@5
|
234 // of widgets just in case a widget has been removed and the form
|
Chris@5
|
235 // hasn't been saved again.
|
Chris@5
|
236 $weight = (isset($this->options['widgets'][$location_id][$widget_id]['weight'])) ? $this->options['widgets'][$location_id][$widget_id]['weight'] : 0;
|
Chris@5
|
237 if ($weight > count($widgets)) {
|
Chris@5
|
238 $weight = count($widgets);
|
Chris@5
|
239 }
|
Chris@5
|
240 $form['widgets'][$location_id][$widget_id]['weight'] = [
|
Chris@5
|
241 '#type' => 'select',
|
Chris@5
|
242 '#title' => $this->t('Weight of the @name', ['@name' => $widget_info['label']]),
|
Chris@5
|
243 '#default_value' => $weight,
|
Chris@5
|
244 '#options' => $weights,
|
Chris@5
|
245 '#description' => $this->t('Determines in what order the @name appears. A lower weight will cause the @name to be above higher weight items.', ['@name' => $widget_info['label']]),
|
Chris@5
|
246 '#prefix' => '<div class="vs-dependent">',
|
Chris@5
|
247 '#suffix' => '</div>',
|
Chris@5
|
248 '#states' => [
|
Chris@5
|
249 'visible' => [
|
Chris@5
|
250 ':input[name="style_options[widgets][' . $location_id . '][' . $widget_id . '][enable]"]' => ['checked' => TRUE],
|
Chris@5
|
251 ],
|
Chris@5
|
252 ],
|
Chris@5
|
253 ];
|
Chris@5
|
254
|
Chris@5
|
255 // Build the appropriate array for the states API.
|
Chris@5
|
256 $widget_dependency = 'style_options[widgets][' . $location_id . '][' . $widget_id . ']';
|
Chris@5
|
257
|
Chris@5
|
258 // Get the current configuration of this widget type.
|
Chris@5
|
259 $configuration = [];
|
Chris@5
|
260 if (!empty($this->options['widgets'][$location_id][$widget_id])) {
|
Chris@5
|
261 $configuration = $this->options['widgets'][$location_id][$widget_id];
|
Chris@5
|
262 }
|
Chris@5
|
263 $configuration['dependency'] = $widget_dependency;
|
Chris@5
|
264 $instance = $widgetTypeManager->createInstance($widget_id, $configuration);
|
Chris@5
|
265
|
Chris@5
|
266 // Get the configuration form of this widget type.
|
Chris@5
|
267 $form['widgets'][$location_id][$widget_id] = $instance->buildConfigurationForm($form['widgets'][$location_id][$widget_id], $form_state);
|
Chris@5
|
268
|
Chris@5
|
269 // Close the vs-dependent wrapper.
|
Chris@5
|
270 $form['widgets'][$location_id][$widget_id]['wrapper_close'] = [
|
Chris@5
|
271 '#markup' => '</div>',
|
Chris@5
|
272 ];
|
Chris@5
|
273 }
|
Chris@5
|
274 }
|
Chris@5
|
275 }
|
Chris@5
|
276 }
|
Chris@5
|
277
|
Chris@5
|
278 // Browse locations and remove the header if no widget is available.
|
Chris@5
|
279 foreach ($location as $location_id => $location_name) {
|
Chris@5
|
280 // If no widget is available, the only key is "header".
|
Chris@5
|
281 if (count(array_keys($form['widgets'][$location_id])) == 1) {
|
Chris@5
|
282 unset($form['widgets'][$location_id]);
|
Chris@5
|
283 }
|
Chris@5
|
284 }
|
Chris@5
|
285
|
Chris@5
|
286 // Remove the widget section header if there is no widget available.
|
Chris@5
|
287 if (empty($form['widgets'])) {
|
Chris@5
|
288 unset($form['widgets']);
|
Chris@5
|
289 unset($form['widgets_header']);
|
Chris@5
|
290 }
|
Chris@5
|
291
|
Chris@5
|
292 $form['views_slideshow_wrapper_close'] = [
|
Chris@5
|
293 '#markup' => '</div>',
|
Chris@5
|
294 ];
|
Chris@5
|
295
|
Chris@5
|
296 // Add a library to style the form.
|
Chris@5
|
297 $form['#attached']['library'] = ['views_slideshow/form'];
|
Chris@5
|
298 }
|
Chris@5
|
299
|
Chris@5
|
300 /**
|
Chris@5
|
301 * {@inheritdoc}
|
Chris@5
|
302 */
|
Chris@5
|
303 public function validateOptionsForm(&$form, FormStateInterface $form_state) {
|
Chris@5
|
304 // Validate all slideshow type plugins values.
|
Chris@5
|
305 $typeManager = \Drupal::service('plugin.manager.views_slideshow.slideshow_type');
|
Chris@5
|
306 foreach ($typeManager->getDefinitions() as $id => $definition) {
|
Chris@5
|
307 $type = $typeManager->createInstance($id);
|
Chris@5
|
308 $type->validateConfigurationForm($form, $form_state);
|
Chris@5
|
309 }
|
Chris@5
|
310 }
|
Chris@5
|
311
|
Chris@5
|
312 /**
|
Chris@5
|
313 * {@inheritdoc}
|
Chris@5
|
314 */
|
Chris@5
|
315 public function submitOptionsForm(&$form, FormStateInterface $form_state) {
|
Chris@5
|
316 // Submit all slideshow type plugins values.
|
Chris@5
|
317 $typeManager = \Drupal::service('plugin.manager.views_slideshow.slideshow_type');
|
Chris@5
|
318 foreach ($typeManager->getDefinitions() as $id => $definition) {
|
Chris@5
|
319 $type = $typeManager->createInstance($id);
|
Chris@5
|
320 $type->submitConfigurationForm($form, $form_state);
|
Chris@5
|
321 }
|
Chris@5
|
322 }
|
Chris@5
|
323
|
Chris@5
|
324 }
|