PluginProbe ʕ •ᴥ•ʔ
Responsive Lightbox & Gallery / 2.7.2
Responsive Lightbox & Gallery v2.7.2
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 / trait-gallery-sanitize.php
responsive-lightbox / includes / galleries Last commit date
class-gallery-api.php 5 months ago class-gallery-base.php 5 months ago class-gallery-config.php 5 months ago class-gallery-design.php 5 months ago class-gallery-field-provider.php 5 months ago class-gallery-images.php 5 months ago class-gallery-lightbox.php 5 months ago class-gallery-misc.php 5 months ago class-gallery-paging.php 5 months ago trait-gallery-ajax.php 4 months ago trait-gallery-duplicate.php 5 months ago trait-gallery-image-methods.php 5 months ago trait-gallery-preview.php 5 months ago trait-gallery-sanitize.php 5 months ago
trait-gallery-sanitize.php
381 lines
1 <?php
2 // exit if accessed directly
3 if ( ! defined( 'ABSPATH' ) )
4 exit;
5
6 /**
7 * Responsive Lightbox Gallery Sanitization Trait.
8 *
9 * Handles field sanitization for gallery data.
10 *
11 * @trait Responsive_Lightbox_Gallery_Sanitize
12 */
13 trait Responsive_Lightbox_Gallery_Sanitize {
14
15 /**
16 * Sanitize field based on type. Internal use only.
17 *
18 * Unified sanitization behavior aligned with settings-base for shared field types.
19 * Gallery-specific types (media_library, media_preview, taxonomy) maintain custom logic.
20 *
21 * @global string $wp_version
22 *
23 * @param string $field Field name
24 * @param mixed $value Field value
25 * @param array $args Field arguments
26 * @return mixed
27 */
28 public function sanitize_field( $field, $value, $args ) {
29 switch ( $args['type'] ) {
30 case 'radio':
31 case 'select':
32 $value = array_key_exists( $value, $args['options'] ) ? $value : $args['default'];
33 break;
34
35 case 'taxonomy':
36 if ( is_array( $value ) ) {
37 if ( isset( $value['id'] ) )
38 $value['id'] = (int) $value['id'];
39 else
40 $value['id'] = 0;
41
42 $value['children'] = isset( $value['children'] );
43 } else
44 $value = $args['default'];
45
46 // flatten taxonomy options if needed
47 if ( ! empty( $args['options'] ) && is_array( $args['options'] ) ) {
48 $terms = [];
49
50 foreach ( $args['options'] as $option_data ) {
51 if ( isset( $option_data['terms'] ) && is_array( $option_data['terms'] ) )
52 $terms += $option_data['terms'];
53 }
54
55 if ( ! empty( $terms ) )
56 $args['options'] = $terms;
57 }
58
59 if ( isset( $value['id'] ) && ! empty( $args['options'] ) && is_array( $args['options'] ) && ! array_key_exists( $value['id'], $args['options'] ) )
60 $value['id'] = 0;
61
62 // validate term exists
63 if ( isset( $value['id'] ) && $value['id'] ) {
64 $term = get_term( $value['id'], $args['taxonomy'] );
65 if ( ! is_a( $term, 'WP_Term' ) )
66 $value['id'] = 0;
67 }
68 break;
69 case 'multiselect':
70 if ( is_array( $value ) ) {
71 if ( $field === 'post_term' ) {
72 $terms = [];
73
74 foreach ( $args['options'] as $data ) {
75 $terms += $data['terms'];
76 }
77
78 $args['options'] = $terms;
79 }
80
81 $values = [];
82
83 foreach ( $value as $subvalue ) {
84 if ( array_key_exists( $subvalue, $args['options'] ) )
85 $values[] = $subvalue;
86 }
87
88 $value = $values;
89 } else
90 $value = $args['default'];
91 break;
92 case 'checkbox':
93 if ( is_array( $value ) && ! empty( $value ) ) {
94 $sort = [];
95
96 foreach ( $value as $sort_key => $bool ) {
97 if ( array_key_exists( $sort_key, $args['options'] ) )
98 $sort[] = $sort_key;
99 }
100
101 $value = $sort;
102 } else
103 $value = [];
104 break;
105
106 case 'boolean':
107 // handle string 'false' from form submissions
108 if ( $value === 'false' )
109 $value = false;
110 else
111 $value = empty( $value ) ? false : true;
112 break;
113
114 case 'range':
115 case 'number':
116 $value = (int) $value;
117
118 // is value lower than?
119 if ( isset( $args['min'] ) && $value < $args['min'] )
120 $value = $args['min'];
121
122 // is value greater than?
123 if ( isset( $args['max'] ) && $value > $args['max'] )
124 $value = $args['max'];
125 break;
126
127 case 'class':
128 $value = trim( $value );
129
130 // more than 1 class?
131 if ( strpos( $value, ' ' ) !== false ) {
132 // get unique valid HTML classes
133 $value = array_unique( array_filter( array_map( 'sanitize_html_class', explode( ' ', $value ) ) ) );
134
135 if ( ! empty( $value ) )
136 $value = implode( ' ', $value );
137 else
138 $value = '';
139 // single class
140 } else
141 $value = sanitize_html_class( $value );
142 break;
143
144 case 'text':
145 $value = trim( sanitize_text_field( $value ) );
146 break;
147
148 case 'textarea':
149 // For gallery fields, allow minimal formatting (line breaks)
150 // Use wp_kses_post for consistency with settings, but strip most HTML
151 $value = wp_kses_post( $value );
152 break;
153
154 case 'color_picker':
155 $value = sanitize_hex_color( $value );
156
157 // fallback to default if invalid
158 if ( empty( $value ) )
159 $value = isset( $args['default'] ) ? $args['default'] : '#666666';
160 break;
161
162 case 'media_library':
163 if ( is_array( $value ) ) {
164 $data = $args['default'];
165
166 if ( rl_current_lightbox_supports( [ 'youtube', 'vimeo' ], 'OR' ) ) {
167 $reindexed_embed = [];
168
169 // check embed items
170 if ( array_key_exists( 'embed', $value ) && is_array( $value['embed'] ) && ! empty( $value['embed'] ) ) {
171 $copy = $value['embed'];
172
173 $index = 0;
174
175 foreach ( $value['embed'] as $embed_id => $embed_data ) {
176 // check url
177 if ( ! array_key_exists( 'url', $embed_data ) ) {
178 unset( $copy[$embed_id] );
179
180 continue;
181 } else
182 $copy[$embed_id]['url'] = esc_url_raw( $embed_data['url'] );
183
184 // check width
185 if ( ! array_key_exists( 'width', $embed_data ) )
186 $copy[$embed_id]['width'] = 0;
187 else
188 $copy[$embed_id]['width'] = (int) $embed_data['width'];
189
190 // check height
191 if ( ! array_key_exists( 'height', $embed_data ) )
192 $copy[$embed_id]['height'] = 0;
193 else
194 $copy[$embed_id]['height'] = (int) $embed_data['height'];
195
196 // check thumbnail url
197 if ( empty( $embed_data['thumbnail_url'] ) )
198 $copy[$embed_id]['thumbnail_url'] = '';
199 else
200 $copy[$embed_id]['thumbnail_url'] = esc_url_raw( $embed_data['thumbnail_url'] );
201
202 // check thumbnail width
203 if ( ! array_key_exists( 'thumbnail_width', $embed_data ) )
204 $copy[$embed_id]['thumbnail_width'] = 0;
205 else
206 $copy[$embed_id]['thumbnail_width'] = (int) $embed_data['thumbnail_width'];
207
208 // check thumbnail height
209 if ( ! array_key_exists( 'thumbnail_height', $embed_data ) )
210 $copy[$embed_id]['thumbnail_height'] = 0;
211 else
212 $copy[$embed_id]['thumbnail_height'] = (int) $embed_data['thumbnail_height'];
213
214 // check title
215 if ( empty( $embed_data['title'] ) )
216 $copy[$embed_id]['title'] = '';
217 else
218 $copy[$embed_id]['title'] = trim( sanitize_text_field( $embed_data['title'] ) );
219
220 // check caption
221 if ( empty( $embed_data['caption'] ) )
222 $copy[$embed_id]['caption'] = '';
223 else
224 $copy[$embed_id]['caption'] = trim( sanitize_textarea_field( $embed_data['caption'] ) );
225
226 // check date
227 if ( empty( $embed_data['date'] ) )
228 $copy[$embed_id]['date'] = '';
229 else
230 $copy[$embed_id]['date'] = date( 'Y-m-d H:i:s', strtotime( $embed_data['date'] ) );
231
232 // new embed id
233 $new_id = 'e' . $index;
234
235 // add embed data
236 $data['embed'][$new_id] = $copy[$embed_id];
237 $data['embed'][$new_id]['id'] = $new_id;
238
239 // add special id
240 $reindexed_embed[$embed_id] = 'em' . $index++;
241 }
242
243 // last replacement is 'em' to avoid replacing same embed ids
244 $reindexed_embed['em'] = 'e';
245
246 // prepare embed additional data
247 $atts_args = [
248 'embed_keys' => array_keys( $data['embed'] ),
249 'providers' => [ 'youtube', 'vimeo' ]
250 ];
251 } else
252 $atts_args = [];
253 } else
254 $atts_args = [];
255
256
257 // check ids
258 if ( array_key_exists( 'ids', $value ) ) {
259 // prepare ids
260 $ids = (string) trim( $value['ids'] );
261
262 if ( $ids !== '' ) {
263 // reindex embed
264 if ( ! empty( $reindexed_embed ) )
265 $ids = str_replace( array_keys( $reindexed_embed ), array_values( $reindexed_embed ), $ids );
266
267 // get unique and non empty attachment ids only
268 $data['ids'] = $this->check_attachments( array_unique( array_filter( explode( ',', $ids ) ) ), $atts_args );
269 } else
270 $data['ids'] = [];
271 }
272
273 // check excluded items
274 if ( array_key_exists( 'exclude', $value ) && is_array( $value['exclude'] ) && ! empty( $value['exclude'] ) ) {
275 // reindex embed
276 if ( ! empty( $reindexed_embed ) )
277 $value['exclude'] = explode( ',', str_replace( array_keys( $reindexed_embed ), array_values( $reindexed_embed ), implode( ',', array_filter( $value['exclude'] ) ) ) );
278
279 // get unique and non empty attachment ids only
280 $data['exclude'] = $this->check_attachments( array_unique( array_filter( $value['exclude'] ) ), $atts_args );
281 }
282
283 $value = $data;
284 } else
285 $value = $args['default'];
286 break;
287
288 case 'media_preview':
289 if ( is_array( $value ) ) {
290 $data = $args['default'];
291
292 // check excluded items
293 if ( array_key_exists( 'exclude', $value ) && is_array( $value['exclude'] ) && ! empty( $value['exclude'] ) ) {
294 $ids = $strings = [];
295
296 foreach ( $value['exclude'] as $exclude_item ) {
297 $item = trim( $exclude_item );
298
299 if ( is_numeric( $item ) )
300 $ids[] = (int) $item;
301 elseif ( $item !== '' )
302 $strings[] = $item;
303 }
304
305 if ( ! empty( $ids ) ) {
306 // get unique and non empty attachment ids only
307 $ids = $this->check_attachments( array_unique( array_filter( $ids ) ) );
308 }
309
310 $data['exclude'] = $ids + $strings;
311 }
312
313 $value = $data;
314 } else
315 $value = $args['default'];
316 }
317
318 return apply_filters( 'rl_sanitize_gallery_field', $value, $args );
319 }
320
321 /**
322 * Sanitize set of fields.
323 *
324 * @param array $items Fields
325 * @param array $data POST data
326 * @param string $tab_id Gallery tab
327 * @param string $menu_item Gallery menu item
328 * @return array
329 */
330 public function sanitize_fields( $items, $data, $tab_id, $menu_item ) {
331 $safedata = [];
332
333 // For config tab in Global mode, determine disabled fields
334 $disabled_fields = [];
335 if ( $tab_id === 'config' && $menu_item === 'default' ) {
336 $rl = Responsive_Lightbox();
337 $default_gallery_fields = $rl->frontend->get_default_gallery_fields();
338 $disabled_fields = array_diff_key( $items, $default_gallery_fields );
339 }
340
341 foreach ( $items as $field => $item ) {
342 // skip this field
343 if ( isset( $item['save'] ) && ! $item['save'] )
344 continue;
345
346 // Skip disabled fields in Global config
347 if ( $tab_id === 'config' && $menu_item === 'default' && isset( $disabled_fields[$field] ) )
348 continue;
349
350 // available field?
351 if ( isset( $data[$tab_id], $data[$tab_id][$menu_item], $data[$tab_id][$menu_item][$field] ) )
352 $safedata[$tab_id][$menu_item][$field] = $this->sanitize_field( $field, $data[$tab_id][$menu_item][$field], $item );
353 // boolean field?
354 elseif ( $item['type'] === 'boolean' )
355 $safedata[$tab_id][$menu_item][$field] = false;
356 // multiple fields?
357 elseif ( $item['type'] === 'multiple' ) {
358 foreach ( $item['fields'] as $subfield => $subitem ) {
359 // Skip disabled subfields in Global config
360 if ( $tab_id === 'config' && $menu_item === 'default' && isset( $disabled_fields[$field] ) )
361 continue;
362
363 // available subfield?
364 if ( isset( $data[$tab_id], $data[$tab_id][$menu_item], $data[$tab_id][$menu_item][$subfield] ) )
365 $safedata[$tab_id][$menu_item][$subfield] = $this->sanitize_field( $subfield, $data[$tab_id][$menu_item][$subfield], $subitem );
366 // boolean subfield?
367 elseif ( $subitem['type'] === 'boolean' )
368 $safedata[$tab_id][$menu_item][$subfield] = false;
369 // any other case
370 else
371 $safedata[$tab_id][$menu_item][$subfield] = $subitem['default'];
372 }
373 // any other case
374 } else
375 $safedata[$tab_id][$menu_item][$field] = $item['default'];
376 }
377
378 return $safedata;
379 }
380 }
381