PluginProbe ʕ •ᴥ•ʔ
Gallery : FooGallery / 3.1.36
Gallery : FooGallery v3.1.36
3.3.2 3.3.3 3.3.0 3.1.31 3.1.32 3.1.34 3.1.36 3.2.0 3.2.6 trunk 1.10.3 2.0.24 2.1.34 2.2.44 2.3.3 2.4.32 3.0.6 3.1.11 3.1.12 3.1.13 3.1.20 3.1.25 3.1.26 3.1.26.1 3.1.26.2
foogallery / includes / admin / class-gallery-metabox-items.php
foogallery / includes / admin Last commit date
class-admin-notice-custom-css.php 2 months ago class-admin-notices.php 2 months ago class-admin.php 2 months ago class-attachment-fields.php 2 months ago class-columns.php 2 months ago class-demo-content.php 2 months ago class-extensions.php 2 months ago class-gallery-attachment-modal.php 2 months ago class-gallery-datasources.php 2 months ago class-gallery-editor.php 2 months ago class-gallery-metabox-fields.php 2 months ago class-gallery-metabox-items.php 2 months ago class-gallery-metabox-settings-helper.php 2 months ago class-gallery-metabox-settings.php 2 months ago class-gallery-metabox-template.php 2 months ago class-gallery-metaboxes.php 2 months ago class-menu.php 2 months ago class-pro-promotion.php 2 months ago class-settings.php 2 months ago class-silent-installer-skin.php 2 months ago class-trial-mode.php 2 months ago demo-content-galleries.php 2 months ago demo-content-images.php 2 months ago index.php 2 months ago pro-features.php 2 months ago view-features.php 2 months ago view-help-demos.php 2 months ago view-help-getting-started.php 2 months ago view-help-pro.php 2 months ago view-help.php 2 months ago view-system-info.php 2 months ago
class-gallery-metabox-items.php
425 lines
1 <?php
2 /**
3 * Class to handle adding the Items metabox to a gallery
4 */
5 if ( ! class_exists( 'FooGallery_Admin_Gallery_MetaBox_Items' ) ) {
6
7 class FooGallery_Admin_Gallery_MetaBox_Items {
8
9 /**
10 * FooGallery_Admin_Gallery_MetaBox_Items constructor.
11 */
12 function __construct() {
13 add_action( 'add_meta_boxes_' . FOOGALLERY_CPT_GALLERY, array( $this, 'add_items_metabox' ), 7 );
14
15 //enqueue assets for the items metabox
16 add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ) );
17
18 // Ajax call for generating a gallery preview
19 add_action( 'wp_ajax_foogallery_preview', array( $this, 'ajax_gallery_preview' ) );
20
21 //handle previews that have no attachments
22 add_action( 'foogallery_template_no_attachments', array( $this, 'preview_no_attachments' ) );
23 }
24
25 public function add_items_metabox( $post ) {
26 add_meta_box(
27 'foogallery_items',
28 __( 'Gallery Items', 'foogallery' ) . '<span class="foogallery-gallery-items-metabox-title spinner is-active"></span>',
29 array( $this, 'render_gallery_items_metabox' ),
30 FOOGALLERY_CPT_GALLERY,
31 'normal',
32 'high'
33 );
34 }
35
36 public function render_gallery_items_metabox( $post ) {
37 $gallery = foogallery_admin_get_current_gallery( $post );
38
39 //attempt to load default gallery settings from another gallery, as per FooGallery settings page
40 $gallery->load_default_settings_if_new();
41
42 //attempt to load default attachments from the settings page
43 if ( $gallery->is_new() ) {
44 $default_attachments = foogallery_get_setting( 'default_gallery_attachments' );
45 if ( !empty($default_attachments) ) {
46 $gallery->attachment_ids = explode( ',', $default_attachments );
47 }
48 }
49
50 $this->prepare_invalid_datasource_for_recovery( $gallery );
51
52 $mode = $gallery->get_meta( 'foogallery_items_view', 'manage' );
53
54 if ( empty($mode) || $gallery->is_new() ) {
55 $mode = 'manage';
56 }
57 $has_items = !$gallery->is_empty();
58
59 do_action( 'foogallery_gallery_metabox_items', $gallery );
60 ?>
61 <?php $this->render_invalid_datasource_notice( $gallery ); ?>
62 <div class="foogallery-hidden foogallery-items-view-switch-container">
63 <div class="foogallery-items-view-switch">
64 <a href="#manage" data-value="manage" data-container=".foogallery-items-view-manage" class="<?php echo $mode==='manage' ? 'current' : ''; ?>"><?php esc_html_e('Manage Items', 'foogallery'); ?></a>
65 <a href="#preview" data-value="preview" data-container=".foogallery-items-view-preview" class="<?php echo $mode==='preview' ? 'current' : ''; ?>"><?php esc_html_e('Gallery Preview', 'foogallery'); ?></a>
66 </div>
67 <div class="foogallery-preview-actions">
68 <button type="button" class="foogallery-preview-refresh-btn" title="<?php esc_attr_e('Refresh Preview', 'foogallery'); ?>">
69 <span class="dashicons dashicons-update"></span>
70 </button>
71 <span></span>
72 <button type="button" class="foogallery-viewport-btn active" data-viewport="desktop" title="<?php esc_attr_e('Desktop View', 'foogallery'); ?>">
73 <span class="dashicons dashicons-desktop"></span>
74 </button>
75 <button type="button" class="foogallery-viewport-btn" data-viewport="tablet" title="<?php esc_attr_e('Tablet View', 'foogallery'); ?>">
76 <span class="dashicons dashicons-tablet"></span>
77 </button>
78 <button type="button" class="foogallery-viewport-btn" data-viewport="mobile" title="<?php esc_attr_e('Mobile View', 'foogallery'); ?>">
79 <span class="dashicons dashicons-smartphone"></span>
80 </button>
81 </div>
82 <span id="foogallery_preview_spinner" class="spinner"></span>
83 <input type="hidden" id="foogallery_items_view_input" value="<?php echo esc_attr( $mode ); ?>" name="<?php echo esc_attr( FOOGALLERY_META_SETTINGS . '[foogallery_items_view]' ); ?>" /> <!-- phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -->
84 </div>
85
86 <div class="foogallery-items-view foogallery-items-view-manage <?php echo $mode==='manage' ? '' : 'hidden'; ?>">
87 <input type="hidden" name="<?php echo esc_attr( FOOGALLERY_CPT_GALLERY ); ?>_nonce" id="<?php echo esc_attr( FOOGALLERY_CPT_GALLERY ); ?>_nonce" value="<?php echo esc_attr( wp_create_nonce( plugin_basename( FOOGALLERY_FILE ) ) ); ?>"/> <!-- phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -->
88 <div class="foogallery-items-list">
89 <div class="foogallery-items-empty <?php echo $has_items ? 'hidden' : ''; ?>" style="padding-top:20px; text-align: center">
90 <p><?php esc_html_e('Your gallery is currently empty. Add items to see a preview.','foogallery'); ?></p>
91 </div>
92 <?php do_action( 'foogallery_gallery_metabox_items_list', $gallery ); ?>
93 </div>
94 <div class="foogallery-items-add <?php echo $has_items ? 'foogallery-hidden' : ''; ?>">
95 <?php do_action( 'foogallery_gallery_metabox_items_add', $gallery ); ?>
96 </div>
97 </div>
98 <div class="foogallery-items-view foogallery-items-view-preview <?php echo $mode==='preview' ? '' : 'foogallery-hidden'; ?>">
99 <!-- Wrap existing preview container -->
100 <div class="foogallery-preview-wrapper viewport-desktop">
101 <div class="foogallery_preview_container <?php echo $mode==='preview' ? '' : 'foogallery-preview-force-refresh'; ?>">
102 <?php
103 if ( $has_items && $mode === 'preview' ) {
104 foogallery_render_gallery( $gallery->ID );
105 } else if ( $has_items && $mode === 'manage' ) {
106 echo '<div style="padding:20px; text-align: center">';
107 echo '<h3>' . esc_html__( 'Generating preview...', 'foogallery' ) . '</h3>';
108 echo '</div>';
109 } else {
110 $this->render_empty_gallery_preview();
111 }
112 ?>
113 </div>
114 </div>
115
116 <div style="clear: both"></div>
117 <?php wp_nonce_field( 'foogallery_preview', 'foogallery_preview', false ); ?>
118 </div>
119 <?php
120 }
121
122 private function prepare_invalid_datasource_for_recovery( $gallery ) {
123 if ( ! is_object( $gallery ) || ! isset( $gallery->datasource_name ) ) {
124 return;
125 }
126
127 $datasource_name = is_scalar( $gallery->datasource_name ) ? trim( (string) $gallery->datasource_name ) : '';
128 if ( '' === $datasource_name ) {
129 return;
130 }
131
132 $datasources = foogallery_gallery_datasources();
133 if ( is_array( $datasources ) && array_key_exists( $datasource_name, $datasources ) ) {
134 $this->prepare_invalid_datasource_value_for_recovery( $gallery );
135 return;
136 }
137
138 $recovered_datasource_name = $this->recover_datasource_name( $datasource_name, $datasources );
139
140 $gallery->_foogallery_invalid_datasource_name = $datasource_name;
141 $gallery->_foogallery_recovered_datasource_name = $recovered_datasource_name;
142 $gallery->_foogallery_recovered_datasource_label = $this->get_datasource_label( $recovered_datasource_name, $datasources );
143 $gallery->datasource_name = $recovered_datasource_name;
144
145 if ( foogallery_default_datasource() === $recovered_datasource_name || ! isset( $gallery->datasource_value ) || ! is_array( $gallery->datasource_value ) ) {
146 $gallery->datasource_value = array();
147 }
148 }
149
150 private function prepare_invalid_datasource_value_for_recovery( $gallery ) {
151 if ( ! isset( $gallery->datasource_name ) || foogallery_default_datasource() === $gallery->datasource_name ) {
152 return;
153 }
154
155 if ( ! isset( $gallery->datasource_value ) || empty( $gallery->datasource_value ) || is_array( $gallery->datasource_value ) ) {
156 return;
157 }
158
159 if ( is_string( $gallery->datasource_value ) ) {
160 $decoded_value = json_decode( stripslashes( $gallery->datasource_value ), true );
161 if ( is_array( $decoded_value ) ) {
162 $gallery->datasource_value = $decoded_value;
163 return;
164 }
165 }
166
167 $gallery->_foogallery_invalid_datasource_value = true;
168 $gallery->_foogallery_recovered_datasource_name = $gallery->datasource_name;
169 $gallery->_foogallery_recovered_datasource_label = $this->get_datasource_label( $gallery->datasource_name, foogallery_gallery_datasources() );
170 $gallery->datasource_value = array();
171 }
172
173 private function recover_datasource_name( $datasource_name, $datasources ) {
174 $candidates = array(
175 str_replace( '-', '_', $datasource_name ),
176 sanitize_key( str_replace( '-', '_', $datasource_name ) ),
177 );
178
179 if ( is_array( $datasources ) ) {
180 foreach ( array_unique( array_filter( $candidates ) ) as $candidate ) {
181 if ( array_key_exists( $candidate, $datasources ) ) {
182 return $candidate;
183 }
184 }
185 }
186
187 $default_datasource = foogallery_default_datasource();
188 if ( is_array( $datasources ) && array_key_exists( $default_datasource, $datasources ) ) {
189 return $default_datasource;
190 }
191
192 if ( is_array( $datasources ) ) {
193 foreach ( $datasources as $datasource_key => $datasource ) {
194 return $datasource_key;
195 }
196 }
197
198 return $default_datasource;
199 }
200
201 private function render_invalid_datasource_notice( $gallery ) {
202 if ( ! is_object( $gallery ) ) {
203 return;
204 }
205
206 $messages = array();
207
208 if ( ! empty( $gallery->_foogallery_invalid_datasource_name ) ) {
209 /* translators: 1: invalid datasource value, 2: recovered datasource label, 3: recovered datasource value. */
210 $messages[] = sprintf(
211 __( 'This gallery has an invalid datasource value "%1$s". FooGallery is temporarily showing the %2$s UI so you can recover it. Update the gallery to save the corrected datasource value "%3$s".', 'foogallery' ),
212 $gallery->_foogallery_invalid_datasource_name,
213 $gallery->_foogallery_recovered_datasource_label,
214 $gallery->_foogallery_recovered_datasource_name
215 );
216 }
217
218 if ( ! empty( $gallery->_foogallery_invalid_datasource_value ) ) {
219 /* translators: %s: recovered datasource label. */
220 $messages[] = sprintf(
221 __( 'This gallery has an invalid datasource configuration value. FooGallery is temporarily showing the %s UI with empty source settings so you can recover it.', 'foogallery' ),
222 $gallery->_foogallery_recovered_datasource_label
223 );
224 }
225
226 if ( empty( $messages ) ) {
227 return;
228 }
229 ?>
230 <div class="notice notice-error inline">
231 <?php foreach ( $messages as $message ) { ?>
232 <p><?php echo esc_html( $message ); ?></p>
233 <?php } ?>
234 </div>
235 <?php
236 }
237
238 private function get_datasource_label( $datasource_name, $datasources ) {
239 if ( is_array( $datasources ) && isset( $datasources[ $datasource_name ] ) && is_array( $datasources[ $datasource_name ] ) ) {
240 $datasource = $datasources[ $datasource_name ];
241 foreach ( array( 'menu', 'label', 'name' ) as $label_key ) {
242 if ( ! empty( $datasource[ $label_key ] ) && is_scalar( $datasource[ $label_key ] ) ) {
243 return (string) $datasource[ $label_key ];
244 }
245 }
246 }
247
248 return $datasource_name;
249 }
250
251 public function render_empty_gallery_preview( $message = '' ) {
252 if ( empty($message) ) {
253 $message = __( 'Please add media to your gallery to see a preview!', 'foogallery' );
254 }
255 echo '<div class="foogallery-preview-empty" style="padding:20px; text-align: center">';
256 echo '<h3>' . esc_html__( 'Please add media to your gallery to see a preview!', 'foogallery' ) . '</h3>';
257 echo '</div>';
258 }
259
260 public function ajax_gallery_preview() {
261 if ( ! check_ajax_referer( 'foogallery_preview', 'foogallery_preview_nonce', false ) ) {
262 wp_send_json_error(
263 array( 'message' => __( 'Invalid security token.', 'foogallery' ) ),
264 403
265 );
266 }
267
268 $post_data = wp_unslash( $_POST );
269 $foogallery_id = isset( $post_data['foogallery_id'] ) ? absint( $post_data['foogallery_id'] ) : 0;
270 if ( ! $foogallery_id ) {
271 wp_send_json_error(
272 array( 'message' => __( 'Invalid gallery ID.', 'foogallery' ) ),
273 400
274 );
275 }
276
277 if ( ! current_user_can( 'edit_post', $foogallery_id ) ) {
278 wp_send_json_error(
279 array( 'message' => __( 'Insufficient permissions.', 'foogallery' ) ),
280 403
281 );
282 }
283
284 $template = isset( $post_data['foogallery_template'] ) ? sanitize_key( $post_data['foogallery_template'] ) : foogallery_default_gallery_template();
285 $template = apply_filters( 'foogallery_preview_template', $template, $foogallery_id );
286
287 //check that the template supports previews
288 $gallery_template = foogallery_get_gallery_template( $template );
289 if ( isset( $gallery_template['preview_support'] ) && true === $gallery_template['preview_support'] ) {
290
291 global $foogallery_gallery_preview;
292
293 $foogallery_gallery_preview = true;
294
295 $attachment_ids = array();
296 if ( isset( $post_data['foogallery_attachments'] ) ) {
297 $attachment_ids = $post_data['foogallery_attachments'];
298 if ( is_string( $attachment_ids ) ) {
299 $attachment_ids = array_map( 'absint', array_filter( explode( ',', $attachment_ids ) ) );
300 } else {
301 $attachment_ids = array_map( 'absint', (array) $attachment_ids );
302 }
303 }
304
305 $args = array(
306 'template' => $template,
307 'attachment_ids' => $attachment_ids,
308 'preview' => true,
309 );
310
311 $args = $this->extract_preview_arguments( $args, $post_data, $template );
312
313 $args = apply_filters( 'foogallery_preview_arguments', $args, $post_data, $template );
314 $args = apply_filters( 'foogallery_preview_arguments-' . $template, $args, $post_data );
315
316 if ( foogallery_is_debug() ) {
317 echo '<pre style="display: none">' . esc_html__( 'Preview Debug Arguments:', 'foogallery' ) . '<br>' . esc_html( print_r( $args, true ) ) . '</pre> <!-- phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -->';
318 }
319
320 do_action( 'foogallery_preview_before_render', $foogallery_id, $args );
321
322 foogallery_render_gallery( $foogallery_id, $args );
323
324 do_action( 'foogallery_preview_after_render', $foogallery_id, $args );
325
326 $foogallery_gallery_preview = false;
327
328 } else {
329 echo '<div style="padding:20px 50px 50px 50px; text-align: center">';
330 echo '<h3>' . esc_html__( 'Preview not available!', 'foogallery' ) . '</h3>';
331 echo esc_html__( 'Sorry, but this gallery template does not support live previews. Please update the gallery in order to see what the gallery will look like.', 'foogallery' );
332 echo '</div>';
333 }
334
335 wp_die();
336 }
337
338 /**
339 * Extract all the preview arguments from the post data
340 *
341 * @param $args
342 * @param $post_data
343 * @param $template
344 *
345 * @return mixed
346 */
347 private function extract_preview_arguments( $args, $post_data, $template ) {
348 if ( array_key_exists( FOOGALLERY_META_SETTINGS, $post_data ) ) {
349 $settings = $post_data[FOOGALLERY_META_SETTINGS];
350 foreach ( $settings as $key => $value ) {
351 if ( strpos( $key, $template . '_' ) === 0 ) {
352 $args[ $this->str_replace_first( $template . '_', '', $key ) ] = $value;
353 }
354 }
355 }
356
357 if ( array_key_exists( FOOGALLERY_META_SORT, $post_data ) ) {
358 $args['sort'] = $this->sanitize_preview_sort( $post_data[FOOGALLERY_META_SORT] );
359 }
360
361 return $args;
362 }
363
364 /**
365 * Sanitize the preview sort value against the available sort options.
366 *
367 * @param string $sort The requested sort value.
368 *
369 * @return string
370 */
371 private function sanitize_preview_sort( $sort ) {
372 $sort = sanitize_text_field( $sort );
373
374 if ( array_key_exists( $sort, foogallery_sorting_options() ) ) {
375 return $sort;
376 }
377
378 return '';
379 }
380
381 function str_replace_first($search, $replace, $subject) {
382 $pos = strpos($subject, $search);
383 if ($pos !== false) {
384 return substr_replace($subject, $replace, $pos, strlen($search));
385 }
386 return $subject;
387 }
388
389 /**
390 * Handle gallery previews where there are no attachments
391 *
392 * @param $foogallery FooGallery
393 */
394 public function preview_no_attachments( $foogallery ) {
395 global $foogallery_gallery_preview;
396
397 if ( isset( $foogallery_gallery_preview ) && true === $foogallery_gallery_preview ) {
398 $message = '';
399 if ( foogallery_default_datasource() !== $foogallery->datasource_name ) {
400 $message = __( 'No items were found for this gallery.', 'foogallery' );
401 }
402 $this->render_empty_gallery_preview( $message );
403 }
404 }
405
406 public function enqueue_assets() {
407 $screen_id = foo_current_screen_id();
408
409 //only include scripts if we on the foogallery add/edit page
410 if ( FOOGALLERY_CPT_GALLERY === $screen_id ||
411 'edit-' . FOOGALLERY_CPT_GALLERY === $screen_id ) {
412
413 //enqueue any dependencies from extensions or gallery templates
414 do_action( 'foogallery_enqueue_preview_dependencies' );
415 //add core foogallery files for preview
416 foogallery_enqueue_core_gallery_template_style();
417 foogallery_enqueue_core_gallery_template_script();
418
419 //make sure we have jquery UI sortable enqueued
420 wp_enqueue_script( 'jquery-ui-sortable');
421 }
422 }
423 }
424 }
425