PluginProbe ʕ •ᴥ•ʔ
Responsive Lightbox & Gallery / trunk
Responsive Lightbox & Gallery vtrunk
2.7.8 trunk 1.0.0 1.0.1 1.0.1.1 1.0.2 1.0.3 1.0.4 1.1.0 1.1.1 1.1.2 1.2.0 1.2.1 1.2.2 1.2.3 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.4.0 1.4.0.1 1.4.1 1.4.11 1.4.12 1.4.13 1.4.14 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.6.0 1.6.1 1.6.10 1.6.11 1.6.12 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 2.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.1 2.2.0 2.2.1 2.2.2 2.2.3 2.2.3.1 2.3.0 2.3.1 2.3.2 2.3.3 2.3.4 2.3.5 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.4.8 2.4.9 2.5.0 2.5.1 2.5.2 2.5.3 2.5.4 2.5.5 2.6.0 2.6.1 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7
responsive-lightbox / includes / galleries / class-gallery-base.php
responsive-lightbox / includes / galleries Last commit date
class-gallery-api.php 4 months ago class-gallery-base.php 4 months ago class-gallery-config.php 4 months ago class-gallery-design.php 4 months ago class-gallery-field-provider.php 4 months ago class-gallery-images.php 4 months ago class-gallery-lightbox.php 4 months ago class-gallery-misc.php 4 months ago class-gallery-paging.php 4 months ago trait-gallery-ajax.php 4 months ago trait-gallery-duplicate.php 4 months ago trait-gallery-image-methods.php 2 weeks ago trait-gallery-preview.php 4 months ago trait-gallery-sanitize.php 4 months ago
class-gallery-base.php
720 lines
1 <?php
2 /**
3 * Responsive Lightbox Gallery Settings Base Class
4 *
5 * Abstract base class for gallery post meta settings tabs.
6 * Adapts Settings API patterns for post meta storage instead of options.
7 *
8 * @package Responsive_Lightbox
9 */
10
11 // exit if accessed directly
12 if ( ! defined( 'ABSPATH' ) )
13 exit;
14
15 /**
16 * Responsive_Lightbox_Gallery_Base class.
17 *
18 * Base class for gallery settings tabs using post meta storage.
19 * Extends Settings_Base but overrides storage methods for post meta.
20 *
21 * @abstract
22 * @class Responsive_Lightbox_Gallery_Base
23 */
24 abstract class Responsive_Lightbox_Gallery_Base extends Responsive_Lightbox_Settings_Base {
25
26 /**
27 * Tab key identifier.
28 *
29 * Must be defined in child class.
30 *
31 * @var string
32 */
33 const TAB_KEY = '';
34
35 /**
36 * Class constructor.
37 *
38 * Registers filters for gallery settings integration.
39 *
40 * @return void
41 */
42 public function __construct() {
43 // provide settings data for this tab
44 add_filter( 'rl_gallery_settings_tabs', [ $this, 'register_tab' ] );
45 }
46
47 /**
48 * Register this tab with the gallery settings system.
49 *
50 * @param array $tabs Existing tabs.
51 * @return array Modified tabs.
52 */
53 public function register_tab( $tabs ) {
54 $tabs[static::TAB_KEY] = $this;
55 return $tabs;
56 }
57
58 /**
59 * Get tab data for rendering.
60 *
61 * Must be implemented by child class.
62 * Should return array with structure compatible with gallery fields.
63 *
64 * @param string $menu_item Optional menu item for tabs with sub-navigation.
65 * @return array Tab data.
66 */
67 abstract public function get_tab_data( $menu_item = '' );
68
69 /**
70 * Provide settings data for Settings API.
71 *
72 * Required by base class but not used in gallery context.
73 * Gallery tabs don't contribute to global settings.
74 *
75 * @param array $data Settings data.
76 * @return array Modified settings data.
77 */
78 public function settings_data( $data ) {
79 return $data;
80 }
81
82 /**
83 * Get field name for form input.
84 *
85 * Adapts Settings API field names to gallery post meta structure.
86 *
87 * @param string $tab_id Tab identifier.
88 * @param string $menu_item Menu item identifier (optional).
89 * @param string $field_key Field key.
90 * @return string Form field name.
91 */
92 protected function get_field_name( $tab_id, $menu_item, $field_key ) {
93 if ( $menu_item ) {
94 return sprintf( 'rl_gallery[%s][%s][%s]', $tab_id, $menu_item, $field_key );
95 }
96 return sprintf( 'rl_gallery[%s][%s]', $tab_id, $field_key );
97 }
98
99 /**
100 * Render field HTML.
101 *
102 * Adapts Settings API field rendering for gallery context.
103 *
104 * @param string $field_key Field key.
105 * @param array $field Field configuration.
106 * @param mixed $value Current value.
107 * @param int $post_id Post ID.
108 * @param string $tab_id Tab ID.
109 * @param string $menu_item Menu item ID.
110 * @return string HTML output.
111 */
112 public function render_field_html( $field_key, $field, $value, $post_id, $tab_id, $menu_item ) {
113 $name = $this->get_field_name( $tab_id, $menu_item, $field_key );
114 // Keep legacy ID contract for Images tab (admin-galleries.js relies on #rl-{tab}-{menu}-{field} selectors).
115 if ( $tab_id === 'images' ) {
116 $id = sanitize_html_class( 'rl-' . $tab_id . '-' . $menu_item . '-' . $field_key );
117 } else {
118 $id = sanitize_key( $name );
119 }
120 $disabled = ! empty( $field['disabled'] ) ? ' disabled="disabled"' : '';
121
122 // Handle field types
123 switch ( $field['type'] ) {
124 case 'text':
125 case 'color':
126 $input_html = sprintf(
127 '<input type="%s" id="%s" name="%s" value="%s" class="regular-text"%s />',
128 esc_attr( $field['type'] ),
129 esc_attr( $id ),
130 esc_attr( $name ),
131 esc_attr( $value ),
132 $disabled
133 );
134
135 // Add append text if specified
136 if ( isset( $field['append'] ) ) {
137 $input_html .= '<span class="rl-field-append">' . esc_html( $field['append'] ) . '</span>';
138 }
139
140 return $input_html;
141
142 case 'number':
143 $attrs = '';
144 if ( isset( $field['min'] ) ) {
145 $attrs .= ' min="' . esc_attr( $field['min'] ) . '"';
146 }
147 if ( isset( $field['max'] ) ) {
148 $attrs .= ' max="' . esc_attr( $field['max'] ) . '"';
149 }
150 if ( isset( $field['step'] ) ) {
151 $attrs .= ' step="' . esc_attr( $field['step'] ) . '"';
152 }
153
154 $input_html = sprintf(
155 '<input type="number" id="%s" name="%s" value="%s" class="small-text"%s%s />',
156 esc_attr( $id ),
157 esc_attr( $name ),
158 esc_attr( $value ),
159 $attrs,
160 $disabled
161 );
162
163 if ( isset( $field['append'] ) ) {
164 $input_html .= '<span class="rl-field-append">' . esc_html( $field['append'] ) . '</span>';
165 }
166
167 return $input_html;
168
169 case 'textarea':
170 $class = isset( $field['class'] ) ? $field['class'] : 'large-text';
171 return sprintf(
172 '<textarea id="%s" name="%s" class="%s"%s>%s</textarea>',
173 esc_attr( $id ),
174 esc_attr( $name ),
175 esc_attr( $class ),
176 $disabled,
177 esc_textarea( $value )
178 );
179
180 case 'select':
181 $options = '';
182 if ( isset( $field['options'] ) && is_array( $field['options'] ) ) {
183 foreach ( $field['options'] as $option_value => $option_label ) {
184 $options .= sprintf(
185 '<option value="%s" %s>%s</option>',
186 esc_attr( $option_value ),
187 selected( $value, $option_value, false ),
188 esc_html( $option_label )
189 );
190 }
191 }
192 return sprintf(
193 '<select id="%s" name="%s"%s>%s</select>',
194 esc_attr( $id ),
195 esc_attr( $name ),
196 $disabled,
197 $options
198 );
199
200 case 'checkbox':
201 $checked_value = false;
202 if ( is_array( $value ) ) {
203 $checked_value = in_array( 1, $value, true ) || in_array( '1', $value, true ) || in_array( true, $value, true );
204 } else {
205 $checked_value = ( $value === 1 || $value === '1' || $value === true );
206 }
207
208 return sprintf(
209 '<input type="checkbox" id="%s" name="%s" value="1" %s%s />',
210 esc_attr( $id ),
211 esc_attr( $name ),
212 checked( $checked_value, true, false ),
213 $disabled
214 );
215
216 case 'boolean':
217 $label = ! empty( $field['label'] ) ? wp_kses_post( $field['label'] ) : '';
218
219 $html = '';
220 if ( empty( $field['disabled'] ) ) {
221 $html .= '<input type="hidden" name="' . esc_attr( $name ) . '" value="false" />';
222 }
223
224 $html .= '<label><input type="checkbox" role="switch" id="' . esc_attr( $id ) . '" name="' . esc_attr( $name ) . '" value="true" ' . checked( (bool) $value, true, false ) . $disabled . ' />' . $label . '</label>';
225
226 return $html;
227
228 case 'color_picker':
229 $color_value = is_string( $value ) && $value !== '' ? $value : ( $field['default'] ?? '#000000' );
230 $color_value = esc_attr( $color_value );
231 $color_name = esc_attr( $name );
232 $input_id = esc_attr( $id );
233 $input_class = 'small-text rl-color-input';
234 $swatch_style = ' style="background-color: ' . $color_value . ';"';
235
236 return '<div class="rl-color-control">'
237 . '<input id="' . $input_id . '" type="text" name="' . $color_name . '" value="' . $color_value . '" class="' . esc_attr( $input_class ) . '"' . $disabled . ' />'
238 . '<button type="button" class="rl-color-swatch"' . $swatch_style . ' aria-label="' . esc_attr__( 'Open color picker', 'responsive-lightbox' ) . '" aria-expanded="false"' . $disabled . '></button>'
239 . '<div class="rl-color-popover" aria-hidden="true"><hex-color-picker class="rl-hex-color-picker" color="' . $color_value . '"></hex-color-picker></div>'
240 . '</div>';
241
242 case 'radio':
243 $radios = '';
244 if ( isset( $field['options'] ) && is_array( $field['options'] ) ) {
245 $display_type = ! empty( $field['display_type'] ) && in_array( $field['display_type'], [ 'horizontal', 'vertical' ], true )
246 ? $field['display_type']
247 : 'horizontal';
248 $group_classes = 'rl-field-group rl-radio-group ' . $display_type;
249 $label_class = 'rl-' . sanitize_html_class( $tab_id . '-' . $menu_item . '-' . $field_key );
250 $radios .= '<div class="' . esc_attr( $group_classes ) . '">';
251
252 foreach ( $field['options'] as $option_value => $option_label ) {
253 $option_id = 'rl-' . $tab_id . '-' . $menu_item . '-' . $field_key . '-' . $option_value;
254 $option_id = sanitize_html_class( $option_id );
255 $radios .= sprintf(
256 '<label class="%s" for="%s"><input id="%s" type="radio" name="%s" value="%s" %s%s /> %s</label> ',
257 esc_attr( $label_class ),
258 esc_attr( $option_id ),
259 esc_attr( $option_id ),
260 esc_attr( $name ),
261 esc_attr( $option_value ),
262 checked( $value, $option_value, false ),
263 $disabled,
264 esc_html( $option_label )
265 );
266 }
267
268 $radios .= '</div>';
269 }
270 return $radios;
271
272 case 'multiselect':
273 $options = '';
274 $selected_values = is_array( $value ) ? array_map( 'strval', $value ) : [];
275
276 if ( isset( $field['options'] ) && is_array( $field['options'] ) ) {
277 foreach ( $field['options'] as $option_value => $option_label ) {
278 // Support grouped options format used by Featured -> Post Term:
279 // [taxonomy] => [ 'label' => 'Taxonomy Name', 'terms' => [ term_id => term_name ] ].
280 if ( is_array( $option_label ) && isset( $option_label['terms'] ) && is_array( $option_label['terms'] ) ) {
281 $group_label = isset( $option_label['label'] ) && is_scalar( $option_label['label'] )
282 ? (string) $option_label['label']
283 : (string) $option_value;
284 $group_options = '';
285
286 foreach ( $option_label['terms'] as $term_value => $term_label ) {
287 if ( ! is_scalar( $term_label ) )
288 continue;
289
290 $selected = in_array( (string) $term_value, $selected_values, true ) ? 'selected="selected"' : '';
291 $group_options .= sprintf(
292 '<option value="%s" %s>%s</option>',
293 esc_attr( $term_value ),
294 $selected,
295 esc_html( (string) $term_label )
296 );
297 }
298
299 if ( $group_options !== '' ) {
300 $options .= sprintf(
301 '<optgroup label="%s">%s</optgroup>',
302 esc_attr( $group_label ),
303 $group_options
304 );
305 }
306
307 continue;
308 }
309
310 if ( ! is_scalar( $option_label ) ) {
311 if ( is_array( $option_label ) && isset( $option_label['label'] ) && is_scalar( $option_label['label'] ) )
312 $option_label = (string) $option_label['label'];
313 else
314 continue;
315 }
316
317 $selected = in_array( (string) $option_value, $selected_values, true ) ? 'selected="selected"' : '';
318 $options .= sprintf(
319 '<option value="%s" %s>%s</option>',
320 esc_attr( $option_value ),
321 $selected,
322 esc_html( (string) $option_label )
323 );
324 }
325 }
326 return sprintf(
327 '<select class="select2" id="%s" name="%s[]" multiple="multiple" style="height: 100px;"%s>%s</select>',
328 esc_attr( $id ),
329 esc_attr( $name ),
330 $disabled,
331 $options
332 );
333
334 case 'taxonomy':
335 return $this->render_taxonomy_field( $field_key, $field, $value, $post_id, $tab_id, $menu_item, $name, $id, $disabled );
336
337 case 'media_preview':
338 return $this->render_media_preview_field( $field_key, $field, $value, $post_id, $tab_id, $menu_item );
339
340 case 'media_library':
341 return $this->render_media_library_field( $field_key, $field, $value, $post_id, $tab_id, $menu_item, $name );
342
343 case 'custom':
344 if ( ! empty( $field['callback'] ) && is_callable( $field['callback'] ) ) {
345 $callback_args = [
346 'name' => $name,
347 'html_id' => $id,
348 'value' => $value,
349 'field' => $field,
350 'field_id' => $field_key,
351 'tab_id' => $tab_id,
352 'menu_item' => $menu_item,
353 'post_id' => $post_id
354 ];
355
356 if ( ! empty( $field['callback_args'] ) && is_array( $field['callback_args'] ) )
357 $callback_args = array_merge( $callback_args, $field['callback_args'] );
358
359 return call_user_func( $field['callback'], $callback_args );
360 }
361
362 return '';
363
364 case 'hidden':
365 $hidden_input = sprintf(
366 '<input type="hidden" id="%s" name="%s" value="%s" />',
367 esc_attr( $id ),
368 esc_attr( $name ),
369 esc_attr( $value )
370 );
371
372 if ( ! empty( $field['callback'] ) && is_callable( $field['callback'] ) ) {
373 $callback_args = [
374 'field' => $field_key,
375 'tab_id' => $tab_id,
376 'menu_item' => $menu_item,
377 'value' => $value,
378 'post_id' => $post_id
379 ];
380
381 $callback_output = '';
382 try {
383 if ( is_array( $field['callback'] ) ) {
384 $reflection = new ReflectionMethod( $field['callback'][0], $field['callback'][1] );
385 } else {
386 $reflection = new ReflectionFunction( $field['callback'] );
387 }
388
389 $callback_output = $reflection->getNumberOfParameters() <= 1
390 ? call_user_func( $field['callback'], $callback_args )
391 : call_user_func( $field['callback'], $field_key, $field, $value, $post_id, $tab_id, $menu_item );
392 } catch ( Exception $e ) {
393 $callback_output = call_user_func( $field['callback'], $field_key, $field, $value, $post_id, $tab_id, $menu_item );
394 }
395
396 $allowed_html = [
397 'span' => [
398 'id' => true,
399 'class' => true,
400 'data-provider' => true,
401 'data-name' => true,
402 'data-value' => true
403 ]
404 ];
405
406 return $hidden_input . wp_kses( (string) $callback_output, $allowed_html );
407 }
408
409 return $hidden_input;
410
411 case 'notice':
412 $content = ! empty( $field['content'] ) ? wp_kses_post( $field['content'] ) : '';
413 $class = ! empty( $field['class'] ) ? ' ' . esc_attr( $field['class'] ) : '';
414 return '<div class="rl-field-notice' . $class . '">' . $content . '</div>';
415
416 default:
417 // Allow add-ons to provide custom rendering for unrecognized field types.
418 // Returns empty string by default; non-empty return replaces text input fallback.
419 $custom_output = apply_filters( 'rl_gallery_render_field', '', $field_key, $field, $value, $post_id, $tab_id, $menu_item, $name, $id );
420
421 if ( $custom_output !== '' ) {
422 return $custom_output;
423 }
424
425 // Unknown field types: render as text input.
426 return sprintf(
427 '<input type="text" id="%s" name="%s" value="%s" class="regular-text" />',
428 esc_attr( $id ),
429 esc_attr( $name ),
430 esc_attr( $value )
431 );
432 }
433 }
434
435 /**
436 * Render a taxonomy dropdown field.
437 *
438 * Used by the Images tab 'folders' menu item for media folder selection.
439 *
440 * @param string $field_key Field key.
441 * @param array $field Field configuration.
442 * @param mixed $value Current value (array with 'id' and 'children' keys).
443 * @param int $post_id Post ID.
444 * @param string $tab_id Tab ID.
445 * @param string $menu_item Menu item ID.
446 * @param string $name Input name.
447 * @param string $id Input id.
448 * @param string $disabled Disabled attribute string.
449 * @return string HTML output.
450 */
451 private function render_taxonomy_field( $field_key, $field, $value, $post_id, $tab_id, $menu_item, $name, $id, $disabled ) {
452 $html = '';
453 $taxonomy = isset( $field['taxonomy'] ) ? $field['taxonomy'] : '';
454 $value_id = is_array( $value ) && isset( $value['id'] ) ? $value['id'] : 0;
455 $value_children = is_array( $value ) && isset( $value['children'] ) ? $value['children'] : false;
456
457 if ( $taxonomy && taxonomy_exists( $taxonomy ) ) {
458 $html = wp_dropdown_categories( [
459 'orderby' => 'name',
460 'order' => 'asc',
461 'show_option_none' => __( 'Root Folder', 'responsive-lightbox' ),
462 'show_option_all' => false,
463 'show_count' => false,
464 'hide_empty' => false,
465 'option_none_value' => 0,
466 'hierarchical' => true,
467 'selected' => $value_id,
468 'taxonomy' => $taxonomy,
469 'hide_if_empty' => false,
470 'echo' => false,
471 'id' => $id,
472 'name' => $name . '[id]'
473 ] );
474 } else {
475 $html = '<select id="' . esc_attr( $id ) . '" name="' . esc_attr( $name ) . '[]"><option value="0">' . esc_html__( 'Root Folder', 'responsive-lightbox' ) . '</option></select> ';
476 }
477
478 if ( $disabled ) {
479 $html = preg_replace( '/<select /', '<select disabled="disabled" ', $html, 1 );
480 }
481
482 if ( ! empty( $field['include_children'] ) ) {
483 $children_id = esc_attr( $id . '-include-children' );
484
485 $html .= '<label class="' . esc_attr( $id ) . '-include-children" for="' . $children_id . '"><input id="' . $children_id . '" type="checkbox" name="' . esc_attr( $name ) . '[children]" value="true" ' . checked( $value_children, true, false ) . $disabled . ' />' . esc_html__( 'Include children.', 'responsive-lightbox' ) . '</label>';
486 }
487
488 return $html;
489 }
490
491 /**
492 * Render a media preview field.
493 *
494 * Used by Images tab menu items (featured, posts, folders, remote_library)
495 * to display a gallery preview with update button and pagination.
496 *
497 * @param string $field_key Field key.
498 * @param array $field Field configuration.
499 * @param mixed $value Current value (array with 'exclude' key).
500 * @param int $post_id Post ID.
501 * @param string $tab_id Tab ID.
502 * @param string $menu_item Menu item ID.
503 * @return string HTML output.
504 */
505 private function render_media_preview_field( $field_key, $field, $value, $post_id, $tab_id, $menu_item ) {
506 $rl = Responsive_Lightbox();
507
508 if ( ! isset( $rl->galleries ) )
509 return '';
510
511 $galleries = $rl->galleries;
512
513 // set menu_item so get_gallery_images() uses the correct image source
514 $galleries->set_menu_item( $menu_item );
515
516 // get images
517 $images = $galleries->get_gallery_images( $post_id );
518
519 // get media item template
520 $preview = isset( $field['preview'] ) ? $field['preview'] : [];
521 $media_item_template = $galleries->get_media_item_template( $preview );
522
523 $html = '
524 <div class="rl-gallery-preview-inside">
525 <a href="#" class="rl-gallery-update-preview button button-secondary">' . esc_html__( 'Update preview', 'responsive-lightbox' ) . '</a><span class="spinner" style="display: none;"></span>
526 <p class="description">' . esc_html__( 'Use this button after any change of the options below to see updated gallery preview.', 'responsive-lightbox' ) . '</p>
527 </div>
528 <div class="rl-gallery-content">
529 <ul class="rl-gallery-images rl-gallery-images-' . esc_attr( $menu_item ) . '">';
530
531 $exclude = [];
532 if ( is_array( $value ) && isset( $value['exclude'] ) ) {
533 if ( is_array( $value['exclude'] ) ) {
534 $exclude = $value['exclude'];
535 } elseif ( is_string( $value['exclude'] ) && $value['exclude'] !== '' ) {
536 $exclude = array_filter( array_map( 'trim', explode( ',', $value['exclude'] ) ), 'strlen' );
537 }
538 }
539
540 if ( ! empty( $images ) ) {
541 foreach ( $images as $image ) {
542 if ( empty( $image['id'] ) ) {
543 $excluded_item = $image['url'];
544 $image['id'] = 0;
545 } else
546 $excluded_item = $image['id'];
547
548 // get image content html
549 $html .= $galleries->get_gallery_preview_image_content( $image, $tab_id, $menu_item, $field_key, $media_item_template, $exclude, $excluded_item );
550 }
551 }
552
553 $html .= '
554 </ul>
555 </div>';
556
557 if ( ! empty( $preview ) && isset( $preview['pagination'] ) && $preview['pagination'] )
558 $html .= $galleries->get_preview_pagination();
559
560 return $html;
561 }
562
563 /**
564 * Render a media library field.
565 *
566 * Used by the Images tab 'media' menu item for image/video selection,
567 * drag-and-drop reordering, and embed video management.
568 *
569 * @param string $field_key Field key.
570 * @param array $field Field configuration.
571 * @param mixed $value Current value (array with 'ids', 'exclude', 'embed' keys).
572 * @param int $post_id Post ID.
573 * @param string $tab_id Tab ID.
574 * @param string $menu_item Menu item ID.
575 * @param string $name Input name.
576 * @return string HTML output.
577 */
578 private function render_media_library_field( $field_key, $field, $value, $post_id, $tab_id, $menu_item, $name ) {
579 $rl = Responsive_Lightbox();
580
581 if ( ! isset( $rl->galleries ) )
582 return '';
583
584 $galleries = $rl->galleries;
585 $data = get_post_meta( $post_id, '_rl_images', true );
586 $data = is_array( $data ) ? $data : [];
587
588 // load images only when saved menu_item is 'media' or we're not doing an AJAX menu switch
589 if ( ( ! empty( $data['menu_item'] ) && $data['menu_item'] === 'media' ) || ! ( wp_doing_ajax() && isset( $_POST['action'] ) && $_POST['action'] === 'rl-get-menu-content' ) )
590 $images = $galleries->get_gallery_images( $post_id );
591 else
592 $images = [];
593
594 // get media item template
595 $preview = isset( $field['preview'] ) ? $field['preview'] : [];
596 $media_item_template = $galleries->get_media_item_template( $preview );
597
598 // build buttons
599 $buttons = [];
600 $buttons_desc = '';
601
602 // video support?
603 if ( rl_current_lightbox_supports( 'video' ) ) {
604 $buttons[] = '<a href="#" class="rl-gallery-select button button-secondary">' . __( 'Select images & videos', 'responsive-lightbox' ) . '</a>';
605 } else {
606 $buttons[] = '<a href="#" class="rl-gallery-select button button-secondary">' . __( 'Select images', 'responsive-lightbox' ) . '</a>';
607 $buttons[] = '<a href="#" class="rl-gallery-select button button-disabled" disabled="true">' . __( 'Select images & videos', 'responsive-lightbox' ) . '</a>';
608 $buttons_desc_args = [ '<a href="http://www.dfactory.co/products/fancybox-pro/" target="_blank">Fancybox Pro</a>', '<a href="http://www.dfactory.co/products/lightgallery-lightbox/" target="_blank">Lightgallery Lightbox</a>', '<a href="http://www.dfactory.co/products/lightcase-lightbox/" target="_blank">Lightcase Lightbox</a>' ];
609 $buttons_desc = '<p class="description">' . wp_sprintf( __( 'HTML5 Videos and Embed Videos available only in %l.', 'responsive-lightbox' ), $buttons_desc_args ) . '</p>';
610 }
611
612 // hidden IDs input
613 $ids = [];
614 if ( is_array( $value ) && isset( $value['ids'] ) ) {
615 if ( is_array( $value['ids'] ) ) {
616 $ids = $value['ids'];
617 } elseif ( is_string( $value['ids'] ) && $value['ids'] !== '' ) {
618 $ids = array_filter( array_map( 'trim', explode( ',', $value['ids'] ) ), 'strlen' );
619 }
620 }
621 $ids_value = implode( ',', $ids );
622
623 $html = '
624 <input type="hidden" class="rl-gallery-ids" name="' . esc_attr( $name ) . '[ids]" value="' . esc_attr( $ids_value ) . '">';
625
626 // embed video support?
627 if ( rl_current_lightbox_supports( [ 'youtube', 'vimeo' ], 'OR' ) )
628 $buttons[] = '<a href="#" class="rl-gallery-select-videos button button-secondary">' . esc_html__( 'Embed videos', 'responsive-lightbox' ) . '</a>';
629 else
630 $buttons[] = '<a href="#" class="rl-gallery-select-videos button button-disabled" disabled="true">' . esc_html__( 'Embed videos', 'responsive-lightbox' ) . '</a>';
631
632 // buttons container
633 $html .= '
634 <div class="rl-gallery-buttons">'
635 . implode( '', $buttons )
636 . $buttons_desc .
637 '</div>';
638
639 // gallery content
640 $html .= '
641 <div class="rl-gallery-content">
642 <ul class="rl-gallery-images rl-gallery-images-media">';
643
644 $exclude = [];
645 if ( is_array( $value ) && isset( $value['exclude'] ) ) {
646 if ( is_array( $value['exclude'] ) ) {
647 $exclude = $value['exclude'];
648 } elseif ( is_string( $value['exclude'] ) && $value['exclude'] !== '' ) {
649 $exclude = array_filter( array_map( 'trim', explode( ',', $value['exclude'] ) ), 'strlen' );
650 }
651 }
652
653 if ( ! empty( $images ) ) {
654 foreach ( $images as $image ) {
655 if ( $image['id'] === 0 )
656 $excluded_item = $image['url'];
657 else
658 $excluded_item = $image['id'];
659
660 // get image content html
661 $html .= $galleries->get_gallery_preview_image_content( $image, $tab_id, $menu_item, $field_key, $media_item_template, $exclude, $excluded_item );
662 }
663 }
664
665 $html .= '
666 </ul>
667 </div>';
668
669 return $html;
670 }
671
672 /**
673 * Check whether a field type self-manages its description output.
674 *
675
676 * Sanitize fields for this tab.
677 *
678 * Uses base class sanitization but adapted for post meta context.
679 *
680 * @param array $input Input data.
681 * @param string $tab_id Tab identifier.
682 * @param string $menu_item Menu item identifier.
683 * @return array Sanitized data.
684 */
685 public function sanitize_tab_fields( $input, $tab_id, $menu_item = '' ) {
686 $fields = $this->get_tab_data();
687
688 if ( $menu_item && isset( $fields[$menu_item] ) ) {
689 $fields = $fields[$menu_item];
690 }
691
692 return $this->sanitize_fields( $input, $tab_id, $fields );
693 }
694
695 /**
696 * Validate settings for this tab (base signature compatibility).
697 *
698 * @param array $input Sanitized data.
699 * @return array Validated data.
700 */
701 public function validate( $input ) {
702 return is_array( $input ) ? $input : [];
703 }
704
705 /**
706 * Validate tab data after sanitization for gallery context.
707 *
708 * Child classes can override to enforce tab-specific validation rules.
709 *
710 * @param array $input Sanitized data for the current tab/menu item.
711 * @param string $tab_id Tab identifier.
712 * @param string $menu_item Menu item identifier.
713 * @param int $post_id Post ID.
714 * @return array Validated data.
715 */
716 public function validate_tab( $input, $tab_id, $menu_item = '', $post_id = 0 ) {
717 return is_array( $input ) ? $input : [];
718 }
719 }
720