PluginProbe
WPVR – 360 Panorama viewer and Virtual Tour Builder for WordPress / 9.0.2
WPVR – 360 Panorama viewer and Virtual Tour Builder for WordPress v9.0.2
9.1.3 9.1.2 9.1.1 9.1.0 9.0.3 9.0.2 9.0.1 9.0.0 8.5.79 8.5.78 8.5.77 8.5.76 8.5.75 8.5.74 8.5.73 8.5.72 8.5.71 8.5.70 8.5.69 8.5.68 8.5.35 8.5.36 8.5.37 8.5.38 8.5.39 All 222 releases
wpvr / legacy / admin / classes / class-wpvr-post-type.php

class-wpvr-post-type.php in WPVR – 360 Panorama viewer and Virtual Tour Builder for WordPress 9.0.2, at legacy/admin/classes/class-wpvr-post-type.php

604 lines 27.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
3 /**
4 * Define the custom post type
5 *
6 *
7 * @link http://rextheme.com/
8 * @since 8.0.0
9 *
10 * @package Wpvr
11 * @subpackage Wpvr/includes/classes
12 */
13
14
15 class WPVR_Post_Type {
16
17 /**
18 * The ID of this plugin.
19 *
20 * @since 8.0.0
21 * @access private
22 * @var string $plugin_name The ID of this plugin.
23 */
24 private $plugin_name;
25
26 /**
27 * The version of this plugin.
28 *
29 * @since 8.0.0
30 * @access private
31 * @var string $version The current version of this plugin.
32 */
33 private $version;
34
35 /**
36 * The post type of this plugin.
37 *
38 * @since 8.0.0
39 */
40 private $post_type;
41
42 /**
43 * Initialize the class and set its properties.
44 *
45 * @since 8.0.0
46 * @param string $plugin_name The name of this plugin.
47 * @param string $version The version of this plugin.
48 */
49 public function __construct($plugin_name, $version, $post_type) {
50
51 $this->plugin_name = $plugin_name;
52 $this->version = $version;
53 $this->post_type = $post_type;
54
55 // Register the post type
56 add_action('init', array($this, 'register'));
57
58 // Admin set post columns
59 add_filter('manage_edit-' . $this->post_type . '_columns', array($this, 'set_columns')) ;
60
61 // Set messages
62 add_filter('post_updated_messages', array($this, 'wpvr_post_updated_messages') );
63
64 // Admin edit post columns
65 add_filter('manage_' . $this->post_type . '_posts_custom_column', array($this, 'edit_columns'));
66
67 add_filter('admin_body_class',array($this, 'add_body_class'));
68
69 add_filter('admin_head',array($this, 'add_javascript_in_wpvr_admin_page'));
70
71 // add_action('admin_footer',array($this, 'add_new_tour_modal'));
72
73
74 }
75
76 /**
77 * Adds a modal for creating a new tour.
78 *
79 * This function checks if the current screen is the post type edit screen and
80 * if so, it displays a modal for creating a new tour. The modal includes options
81 * for selecting the tour type, entering the tour name, and submitting the form.
82 *
83 * @return void
84 */
85 public function add_new_tour_modal()
86 {
87 $current_screen = get_current_screen();
88
89 if(!empty($current_screen->post_type) && $current_screen->post_type == $this->post_type && $current_screen->base == 'edit'){
90
91 $radio_icon = '<svg width="27" height="27" fill="none" viewBox="-3 -3 25 25" xmlns="http://www.w3.org/2000/svg"><rect width="19" height="19" x=".5" y=".5" fill="#fff" class="rect1" rx="9.5"/><rect width="19" height="19" x=".5" y=".5" stroke="#D8CCFF" class="rect2" rx="9.5"/><circle cx="10" cy="10" r="5" fill="#3F04FE"/></svg>';
92 ?>
93 <!-- start add new tour modal -->
94 <div class="wpvr-create-tour-modal">
95 <div class="wpvr-create-tour-inner">
96 <div class="wpvr-create-tour-modal-wrapper">
97 <div class="wpvr-create-tour-modal-header">
98 <h4 class="wpvr-create-tour-modal-title"><?php echo esc_html__( 'Create Tour', 'wpvr' ); ?></h4>
99 <button type="button" class="wpvr-create-tour-modal-close" aria-label="Close modal">
100 <svg width="22" height="22" fill="none" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg"><g stroke="#B0AAC5" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" clip-path="url(#clip0_874_3238)"><path d="M16.5 5.5l-11 11m0-11l11 11"/></g><defs><clipPath id="clip0_874_3238"><path fill="#fff" d="M0 0h22v22H0z"/></clipPath></defs></svg>
101 </button>
102 </div>
103
104 <div class="wpvr-create-tour-modal-content">
105 <div class="wpvr-modal-form-group tour-type-group">
106 <label class="field-label">
107 <?php echo esc_html__( 'Select your preferred tour', 'wpvr' ); ?>
108 </label>
109
110 <div class="tour-type-wrapper">
111 <label class="single-tour-type">
112 <input type="radio" name="tour-type" value="image-tour" checked>
113 <span class="radio-box">
114 <?php echo wp_kses_post( $radio_icon ); ?>
115
116 <span class="radio-label">
117 <?php echo esc_html__( '360 Image Tour', 'wpvr' ); ?>
118 </span>
119 </span>
120 </label>
121
122 <label class="single-tour-type">
123 <input type="radio" name="tour-type" value="video-tour">
124 <span class="radio-box">
125 <?php echo wp_kses_post( $radio_icon ); ?>
126
127 <span class="radio-label">
128 <?php echo esc_html__( '360 Video Tour', 'wpvr' ); ?>
129 </span>
130 </span>
131 </label>
132
133 <label class="single-tour-type <?php echo !defined('WPVR_PRO_VERSION') ? esc_attr('is-pro') : ''; ?>">
134
135 <?php if(defined('WPVR_PRO_VERSION')){ ?>
136 <input type="radio" name="tour-type" value="street-view-tour">
137 <?php } ?>
138
139 <span class="radio-box">
140 <?php echo wp_kses_post( $radio_icon ); ?>
141
142 <span class="radio-label">
143 <?php echo esc_html__( 'Street View', 'wpvr' ); ?>
144 </span>
145
146 <?php if(!defined('WPVR_PRO_VERSION')){ ?>
147 <span class="pro-tag"><?php echo esc_html__( 'pro', 'wpvr' ); ?></span>
148 <?php } ?>
149 </span>
150 </label>
151
152 <label class="single-tour-type <?php echo !defined('WPVR_PRO_VERSION') ? esc_attr('is-pro') : ''; ?>">
153 <?php if(defined('WPVR_PRO_VERSION')){ ?>
154 <input type="radio" name="tour-type" value="bg-tour">
155 <?php } ?>
156 <span class="radio-box">
157 <?php echo wp_kses_post( $radio_icon ); ?>
158
159 <span class="radio-label">
160 <?php echo esc_html__( 'Background Tour', 'wpvr' ); ?>
161 </span>
162
163 <?php if(!defined('WPVR_PRO_VERSION')){ ?>
164 <span class="pro-tag"><?php echo esc_html__( 'pro', 'wpvr' ); ?></span>
165 <?php } ?>
166 </span>
167 </label>
168
169 </div>
170 </div>
171
172 <div class="wpvr-modal-form-group">
173 <label class="field-label">
174 <?php echo esc_html__( 'Tour Name', 'wpvr' ); ?>
175 </label>
176 <input type="text" class="wpvr-tour-name-input" placeholder="Enter name">
177 </div>
178 </div>
179
180 <div class="wpvr-create-tour-modal-footer">
181 <div class="modal-action-buttons">
182 <button type="button" class="wpvr-modal-btn modal-cancel" aria-label="Cancel modal"><?php echo esc_html__( 'Cancel', 'wpvr' ); ?></button>
183
184 <button type="button" class="wpvr-modal-btn modal-submit" aria-label="Submit modal"><?php echo esc_html__( 'Create Tour', 'wpvr' ); ?></button>
185 </div>
186 </div>
187 </div>
188 </div>
189 </div>
190 <!-- end add new tour modal -->
191 <?php
192
193 }
194 }
195
196 /**
197 * Adds JavaScript functionality to the WPVR admin page.
198 *
199 * This function checks if the current screen is the WPVR admin page and if so,
200 * it adds JavaScript code to modify the page's behavior. The JavaScript code
201 * includes event listeners for various elements on the page, such as the
202 * page title action button, the create tour modal, and the tour type radio
203 * buttons. It also handles the creation of a new tour based on the selected
204 * tour type and title.
205 *
206 * @return void
207 */
208 public function add_javascript_in_wpvr_admin_page()
209 {
210 $current_screen = get_current_screen();
211
212 if(!empty($current_screen->post_type) && $current_screen->post_type == $this->post_type && $current_screen->base == 'edit'){
213 ?>
214 <script type="text/javascript">
215 document.addEventListener('DOMContentLoaded', function () {
216 var searchInput = document.querySelector('#post-search-input');
217 if (searchInput) {
218 searchInput.placeholder = 'Search Tour...';
219 }
220 });
221
222
223 /**
224 * Adds event listeners to the wpvrPageTitleAction element.
225 *
226 * When the wpvrPageTitleAction element is clicked, the following actions are performed:
227 * 1. Prevent the default behavior of the click event.
228 * 2. Show the createTourModal element.
229 * 3. Hide the createTourModal element when the tourCloseButton is clicked.
230 * 4. Hide the createTourModal element when the TourCancelButton is clicked.
231 * 5. Hide the createTourModal element when clicking outside of the modal-content but inside the modal.
232 * 6. Prevent closing the createTourModal element when clicking inside the createTourModalWrapper.
233 */
234
235 // document.addEventListener('DOMContentLoaded', function () {
236 // let wpvrPageTitleAction = document.querySelector('.page-title-action');
237 // let createTourModal = document.querySelector('.wpvr-create-tour-modal');
238 // let tourCloseButton = document.querySelector('.wpvr-create-tour-modal-close');
239 // let TourCancelButton = document.querySelector('.wpvr-modal-btn.modal-cancel');
240 // let createTourModalInner = document.querySelector('.wpvr-create-tour-inner');
241 // let createTourModalWrapper = document.querySelector('.wpvr-create-tour-modal-wrapper');
242
243
244 // wpvrPageTitleAction.addEventListener('click', function (e) {
245 // e.preventDefault();
246
247 // // Show the modal
248 // createTourModal.classList.add('show');
249 // });
250
251
252 // // Hide the modal when clicking the close button
253 // tourCloseButton.addEventListener('click', function() {
254 // createTourModal.classList.remove('show');
255 // });
256
257 // // Hide the modal when clicking the cancel button
258 // TourCancelButton.addEventListener('click', function() {
259 // createTourModal.classList.remove('show');
260 // });
261
262 // // Hide the modal when clicking outside of the modal-content but inside the modal
263 // window.addEventListener('click', function(event) {
264 // if (event.target === createTourModalInner) {
265 // createTourModal.classList.remove('show');
266 // }
267 // });
268
269 // // Prevent closing the modal when clicking inside the modal-wrapper
270 // createTourModalWrapper.addEventListener('click', function(event) {
271 // event.stopPropagation();
272 // });
273
274
275 // // Get the radio buttons and input field
276 // let radioButtons = document.querySelectorAll('input[name="tour-type"]');
277 // let inputField = document.querySelector('.wpvr-tour-name-input');
278 // let createTour = document.querySelector('.wpvr-modal-btn.modal-submit');
279 // var tourType = 'image-tour';
280 // var tourTitle = '';
281
282 // // Function to handle radio button change
283 // function handleRadioChange() {
284 // tourType = document.querySelector('input[name="tour-type"]:checked').value;
285 // }
286
287 // // Function to handle input field change
288 // function handleInputChange() {
289 // tourTitle = inputField.value;
290 // }
291
292 // // Attach event listeners to radio buttons
293 // radioButtons.forEach(function(radio) {
294 // radio.addEventListener('change', handleRadioChange);
295 // });
296
297 // // Attach event listener to input field
298 // inputField.addEventListener('input', handleInputChange);
299
300 // // Attach event listener to create tour button
301 // createTour.addEventListener('click', function (e) {
302 // let targetLink = '<?php //echo get_admin_url() ?>post-new.php?post_type=wpvr_item&tour_type='+tourType+'&tour_title='+tourTitle+'';
303 // window.location.href = targetLink;
304 // });
305
306 // });
307 </script>
308 <?php
309
310 }
311
312
313 /**
314 * Sets the value of the title input field with the tour title.
315 *
316 * This code is executed when the current screen is the post editor for the WPVR post type,
317 * the action is 'add', and the tour_title parameter is provided in the URL query string.
318 *
319 * @param WP_Screen $current_screen The current screen object.
320 */
321
322 // if(!empty($current_screen->post_type) && $current_screen->post_type == $this->post_type && $current_screen->base == 'post' && $current_screen->action == 'add') {
323 // $tour_title = $_GET['tour_title'];
324
325 ?>
326 <!-- <script type="text/javascript">
327 document.addEventListener('DOMContentLoaded', function () {
328 var titleInput = document.querySelector('#titlewrap #title');
329
330 if (titleInput) {
331 titleInput.value = '<?php //echo $tour_title ?>';
332 }
333 });
334 </script> -->
335 <?php
336 //}
337
338 }
339
340 /**
341 * Adds a custom body class (.wpvr-tour-list) to the admin page.
342 *
343 * @return string The custom body class.
344 */
345 public function add_body_class($classes)
346 {
347 $current_screen = get_current_screen();
348 if (!empty($current_screen->post_type) && $current_screen->post_type == $this->post_type && $current_screen->base == 'edit') {
349 $classes .= ' wpvr-tour-list';
350 }
351
352 return $classes;
353 }
354
355 /**
356 * Register the custom post type
357 *
358 * @since 8.0.0
359 */
360 public function register()
361 {
362 $labels = array(
363 'name' => __('Tours', 'wpvr'),
364 'singular_name' => __('Tours', 'wpvr'),
365 'add_new' => __('Add New Tour', 'wpvr'),
366 'add_new_item' => __('Add New Tour', 'wpvr'),
367 'edit_item' => __('Edit Tour', 'wpvr'),
368 'new_item' => __('New Tour', 'wpvr'),
369 'view_item' => __('View Tour', 'wpvr'),
370 'search_items' => __('Search WP VR Tour', 'wpvr'),
371 'not_found' => __('No WP VR Tour found', 'wpvr'),
372 'not_found_in_trash'=> __('No WP VR Tour found in Trash', 'wpvr'),
373 'parent_item_colon' => '',
374 'all_items' => __('All Tours', 'wpvr'),
375 'menu_name' => __('WP VR', 'wpvr'),
376 );
377
378 $args = array(
379 'labels' => $labels,
380 'public' => false,
381 'show_ui' => true,
382 'show_in_menu' => false,
383 'menu_position' => 100,
384 'supports' => array( 'title' ),
385 'menu_icon' => plugins_url(). '/wpvr/images/icon.png',
386 'capabilities' => array(
387 'edit_post' => 'edit_wpvr_tour',
388 'edit_posts' => 'edit_wpvr_tours',
389 'edit_others_posts' => 'edit_other_wpvr_tours',
390 'publish_posts' => 'publish_wpvr_tours',
391 'read_post' => 'read_wpvr_tour',
392 'read_private_posts' => 'read_private_wpvr_tours',
393 'delete_post' => 'delete_wpvr_tour'
394 ),
395 'map_meta_cap' => true,
396 );
397
398 /**
399 * Documentation : https://codex.wordpress.org/Function_Reference/register_post_type
400 */
401 register_post_type($this->post_type, $args);
402 }
403
404 public function copy_shortcode_html( $post_id = 0 )
405 {
406 $shortcode = '[wpvr id="' . intval( $post_id ) . '"]';
407 $copy = '<button type="button" class="wpvr-copy-shortcode-listing" data-shortcode="' . esc_attr( $shortcode ) . '" title="Copy shortcode" aria-label="Copy shortcode">
408 <svg width="19" height="19" fill="none" viewBox="0 0 19 19" xmlns="http://www.w3.org/2000/svg"><path stroke="#73707D" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M16.3 6.95H8.65a1.7 1.7 0 00-1.7 1.7v7.65a1.7 1.7 0 001.7 1.7h7.65a1.7 1.7 0 001.7-1.7V8.65a1.7 1.7 0 00-1.7-1.7z"/><path stroke="#73707D" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M3.55 12.05H2.7a1.7 1.7 0 01-1.7-1.7V2.7A1.7 1.7 0 012.7 1h7.65a1.7 1.7 0 011.7 1.7v.85"/></svg>
409 </button>';
410
411 return $copy;
412 }
413
414 /**
415 * @param $columns
416 * @return mixed
417 *
418 * Choose the columns you want in
419 * the admin table for this post
420 * @since 8.0.0
421 */
422 public function set_columns($columns) {
423 $checkbox = isset($columns['cb']) ? $columns['cb'] : '<input type="checkbox" />';
424
425 // Set/unset post type table columns.
426 $columns = array(
427 'cb' => $checkbox,
428 'title' => __('Title', 'wpvr'),
429 'thumbnail' => __('Tour Thumbnail', 'wpvr'),
430 'shortcode' => __('Shortcode', 'wpvr'),
431 'type' => __('Tour Type', 'wpvr'),
432 'author' => __('Author', 'wpvr'),
433 'date' => __('Date', 'wpvr')
434 );
435 return $columns;
436 }
437
438 /**
439 * @param $column
440 * @param $post_id
441 *
442 * Edit the contents of each column in
443 * the admin table for this post
444 * @since 8.0.0
445 */
446 public function edit_columns($column) {
447 // Post type table column content
448 $post = get_post();
449 $postdata = get_post_meta($post->ID, 'panodata', true);
450
451 $image_tour_icon = '<svg width="16" height="16" fill="none" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path stroke="#73707D" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.2" d="M5.9 15h4.2c3.5 0 4.9-1.4 4.9-4.9V5.9C15 2.4 13.6 1 10.1 1H5.9C2.4 1 1 2.4 1 5.9v4.2C1 13.6 2.4 15 5.9 15z"/><path stroke="#73707D" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.2" d="M5.9 6.6a1.4 1.4 0 100-2.8 1.4 1.4 0 000 2.8zm-4.431 6.265l3.45-2.317c.554-.37 1.352-.329 1.849.098l.23.203c.547.47 1.429.47 1.975 0l2.912-2.499c.546-.469 1.428-.469 1.974 0l1.14.98"/></svg>';
452
453 $video_tour_icon = '<svg width="14" height="14" fill="none" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg"><path fill="#73707D" d="M13.168 5.922a1.344 1.344 0 00-1.468.292l-.255.255a2.937 2.937 0 00-1.277-1.433 2.908 2.908 0 00.914-2.12 2.915 2.915 0 00-5.25-1.748A2.913 2.913 0 003.5 0 2.92 2.92 0 00.583 2.917c0 .834.352 1.587.915 2.12A2.919 2.919 0 000 7.583v3.5A2.92 2.92 0 002.917 14H8.75a2.922 2.922 0 002.695-1.802l.256.255a1.343 1.343 0 001.467.292 1.34 1.34 0 00.831-1.244V7.168c0-.547-.326-1.036-.83-1.245zM8.166 1.167c.965 0 1.75.785 1.75 1.75s-.785 1.75-1.75 1.75c-.964 0-1.75-.785-1.75-1.75s.786-1.75 1.75-1.75zm-4.666 0c.965 0 1.75.785 1.75 1.75s-.785 1.75-1.75 1.75-1.75-.785-1.75-1.75.785-1.75 1.75-1.75zm7 9.917c0 .964-.786 1.75-1.75 1.75H2.917c-.965 0-1.75-.786-1.75-1.75v-3.5c0-.965.785-1.75 1.75-1.75H8.75c.964 0 1.75.785 1.75 1.75v3.5zm2.333.416c0 .1-.06.146-.112.167a.17.17 0 01-.196-.04l-.859-.858V7.898l.859-.859A.17.17 0 0112.72 7a.17.17 0 01.112.167V11.5z"/></svg>';
454
455 $streetview_icon = '<svg width="16" height="17" fill="none" viewBox="0 0 16 17" xmlns="http://www.w3.org/2000/svg"><path stroke="#73707D" stroke-miterlimit="10" stroke-width="1.2" d="M6.74 16l1.015-1.278-1.015-1.278"/><path stroke="#73707D" stroke-miterlimit="10" stroke-width="1.2" d="M6.37 10.507C3.305 10.71 1 11.566 1 12.592c0 1.177 3.024 2.13 6.754 2.13m2.188-.114c2.656-.287 4.566-1.08 4.566-2.016 0-1.01-2.227-1.855-5.217-2.074m-.184-8.165a1.352 1.352 0 10-2.705 0 1.352 1.352 0 002.705 0z"/><path stroke="#73707D" stroke-miterlimit="10" stroke-width="1.2" d="M10.275 6.226v.952c0 .578-.468 1.045-1.045 1.045v3.566H6.28V8.223a1.045 1.045 0 01-1.046-1.045v-.952a2.52 2.52 0 115.041 0z"/></svg>';
456
457
458
459 switch ($column) {
460 case 'shortcode':
461 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- SVG icon is hardcoded, not user input
462 echo '<div class="wpvr-listing-shortcode"><span class="wpvr-code">[wpvr id="' . esc_attr($post->ID) . '"] </span>' . $this->copy_shortcode_html( $post->ID ) . '</div>';
463 break;
464
465 case 'thumbnail':
466 $scene_image = !empty($postdata['preview']) ? $postdata['preview'] : $this->get_scene_image($postdata);
467
468 if ($scene_image) {
469 echo '<img loading="lazy" src="' . esc_url($scene_image) . '" class="wpvr-thumbnail-image" alt="thumbnail" width="73" height="54">';
470 }else {
471 echo wp_kses_post('<svg width="74" height="54" fill="none" viewBox="0 0 74 54" xmlns="http://www.w3.org/2000/svg"><rect width="73.517" height="54" fill="#E3E3E3" rx="5"/><path stroke="#73707D" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.2" d="M34.9 34h4.2c3.5 0 4.9-1.4 4.9-4.9v-4.2c0-3.5-1.4-4.9-4.9-4.9h-4.2c-3.5 0-4.9 1.4-4.9 4.9v4.2c0 3.5 1.4 4.9 4.9 4.9z"/><path stroke="#73707D" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.2" d="M34.9 25.6a1.4 1.4 0 100-2.8 1.4 1.4 0 000 2.8zm-4.431 6.265l3.45-2.317c.554-.37 1.352-.329 1.849.098l.23.203c.547.47 1.429.47 1.975 0l2.912-2.499c.546-.469 1.428-.469 1.974 0l1.14.98"/></svg>');
472 }
473
474 break;
475
476 case 'type':
477 if (isset($postdata['streetviewdata'])) {
478 echo wp_kses_post('<span class="tour-type">' . $streetview_icon . 'Street View</span>');
479
480 } elseif (isset($postdata['vidid'])) {
481 echo wp_kses_post('<span class="tour-type">' . $video_tour_icon . '360 Video</span>');
482
483 } else {
484 echo wp_kses_post('<span class="tour-type">' . $image_tour_icon . ' 360 Image</span>');
485 }
486 break;
487
488 default:
489 break;
490 }
491 }
492
493 /**
494 * Get the scene image for the post
495 *
496 * @param $postdata array The post meta data
497 * @return string
498 * @since 8.5.22
499 */
500 private function get_scene_image($postdata) {
501 if (!empty($postdata['panodata']['scene-list'][1]['scene-type']) && $postdata['panodata']['scene-list'][1]['scene-type'] === 'equirectangular') {
502 $image_src = $postdata['panodata']['scene-list'][1]['scene-attachment-url'] ?? '';
503 $thumbnail = $this->wpvr_fetch_thumbnail($image_src);
504 if ($thumbnail) {
505 return $thumbnail;
506 }
507 }
508
509 $image_src_face = $postdata['panodata']['scene-list'][1]['scene-attachment-url-face0'] ?? '';
510 return $this->wpvr_fetch_thumbnail($image_src_face);
511 }
512
513 /**
514 * Fetches the thumbnail for the given image URL
515 *
516 * @param string $image_url The URL of the image
517 * @return string The URL of the thumbnail
518 * @since 8.5.22
519 */
520 private function wpvr_fetch_thumbnail($image_url) {
521 if (empty($image_url)) {
522 return '';
523 }
524
525 $attachment_id = attachment_url_to_postid($image_url);
526 if ($attachment_id) {
527 $thumb_url = wp_get_attachment_image_url($attachment_id, 'thumbnail');
528 if ($thumb_url) {
529 return $thumb_url;
530 }
531 }
532
533 $attachment_id = $this->wpvr_get_attachment_id_by_url($image_url);
534 if ($attachment_id) {
535 $thumb_url = wp_get_attachment_image_url($attachment_id, 'thumbnail');
536 if ($thumb_url) {
537 return $thumb_url;
538 }
539 }
540
541 return $this->wpvr_generate_thumbnail($image_url);
542 }
543
544 /**
545 * Get the attachment ID by URL
546 *
547 * @param string $image_url The URL of the image
548 * @return int The ID of the attachment
549 * @since 8.5.22
550 */
551 private function wpvr_get_attachment_id_by_url($image_url) {
552 global $wpdb;
553 $cache_key = 'wpvr_attachment_id_' . md5($image_url);
554 $attachment_id = wp_cache_get($cache_key, 'wpvr');
555 if (false === $attachment_id) {
556 $attachment_id = $wpdb->get_var($wpdb->prepare(
557 "SELECT ID FROM $wpdb->posts WHERE guid=%s AND post_type='attachment'",
558 $image_url
559 ));
560 wp_cache_set($cache_key, $attachment_id, 'wpvr', 12 * HOUR_IN_SECONDS);
561 }
562 return $attachment_id;
563 }
564
565 /**
566 * Generates a thumbnail for the given image URL
567 *
568 * @param string $image_url The URL of the image
569 * @return string The URL of the thumbnail
570 * @since 8.5.22
571 */
572 private function wpvr_generate_thumbnail($image_url) {
573 $uploads_dir = wp_upload_dir();
574 $image_path = str_replace($uploads_dir['baseurl'], $uploads_dir['basedir'], $image_url);
575
576 if (file_exists($image_path)) {
577 $image = wp_get_image_editor($image_path);
578 if (!is_wp_error($image)) {
579 $thumb_path = dirname($image_path) . '/thumb-' . basename($image_path);
580 $image->resize(150, 150, true);
581 $image->save($thumb_path);
582 return str_replace($uploads_dir['basedir'], $uploads_dir['baseurl'], $thumb_path);
583 }
584 }
585
586 return $image_url;
587 }
588
589
590 /**
591 * Sets the messages for the custom post type
592 *
593 * @since 8.0.0
594 */
595 public function wpvr_post_updated_messages($messages)
596 {
597 $messages[$this->post_type][1] = __('WP VR item updated.', 'wpvr');
598 $messages[$this->post_type][4] = __('WP VR item updated.', 'wpvr');
599
600 return $messages;
601 }
602
603 }
604