PluginProbe
WPVR – 360 Panorama viewer and Virtual Tour Builder for WordPress / 9.1.3
WPVR – 360 Panorama viewer and Virtual Tour Builder for WordPress v9.1.3
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 / class-wpvr-admin.php

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

872 lines 34.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * The admin-specific functionality of the plugin.
5 *
6 * @link http://rextheme.com/
7 * @since 8.0.0
8 *
9 * @package Wpvr
10 * @subpackage Wpvr/admin
11 */
12
13 /**
14 * The admin-specific functionality of the plugin.
15 *
16 * Defines the plugin name, version, and two examples hooks for how to
17 * enqueue the admin-specific stylesheet and JavaScript.
18 *
19 * @package Wpvr
20 * @subpackage Wpvr/admin
21 * @author Rextheme <support@rextheme.com>
22 */
23 class Wpvr_Admin {
24
25 /**
26 * The ID of this plugin.
27 *
28 * @since 8.0.0
29 * @access private
30 * @var string $plugin_name The ID of this plugin.
31 */
32 private $plugin_name;
33
34 /**
35 * The version of this plugin.
36 *
37 * @since 8.0.0
38 * @access private
39 * @var string $version The current version of this plugin.
40 */
41 private $version;
42
43 /**
44 * The post type of this plugin.
45 *
46 * @since 8.0.0
47 */
48 private $post_type;
49
50 /**
51 * Instance of WPVR_Admin_Page class
52 *
53 * @var object
54 * @since 8.0.0
55 */
56 private $plugin_admin_page;
57
58 /**
59 * Instance of WPVR_Setup_Meta_Box class
60 *
61 * @var object
62 * @since 8.0.0
63 */
64 private $setup_metabox;
65
66 /**
67 * Instacne of WPVR_Tour_Preview class
68 *
69 * @var object
70 * @since 8.0.0
71 */
72 private $preview_metabox;
73
74 /**
75 * Instance of Wpvr_Ajax class
76 *
77 * @var object
78 * @since 8.0.0
79 */
80 private $plugin_admin_ajax;
81
82 /**
83 * Instance of WPVR_Post_Type class
84 *
85 * @var object
86 * @since 8.0.0
87 */
88 private $wpvr_post_type;
89
90 /**
91 * Instacne of WPVR_Tour_Preview class
92 *
93 * @var object
94 * @since 8.5.24
95 */
96 private $checklist_metabox;
97
98
99 /**
100 * Initialize the class and set its properties.
101 *
102 * @since 8.0.0
103 * @param string $plugin_name The name of this plugin.
104 * @param string $version The version of this plugin.
105 * @param string $post_type Post type of this plugin
106 */
107 public function __construct($plugin_name, $version, $post_type) {
108
109 $this->plugin_name = $plugin_name;
110 $this->version = $version;
111 $this->post_type = $post_type;
112
113 $this->wpvr_post_type = new WPVR_Post_Type($this->plugin_name, $this->version, $this->post_type);
114 $this->plugin_admin_page = WPVR_Admin_Page::getInstance();
115
116 add_action('admin_init', array($this, 'set_custom_meta_box'));
117
118 // // Add the import button to the All Tours page
119 add_action('admin_footer', array($this, 'add_import_button'));
120 add_action('admin_footer', array($this, 'enqueue_deactivation_scripts'), 99);
121 add_filter('post_states_html', array($this, 'add_imported_tour_badge'), 10, 3);
122 add_action('post_updated', array($this, 'remove_imported_tour_badge'), 10, 2);
123
124 $this->plugin_admin_ajax = new Wpvr_Ajax();
125 }
126
127
128 /**
129 * Add an Imported badge to imported tours in the admin list.
130 *
131 * @param string $post_states_html Post states markup.
132 * @param array $post_states Post states.
133 * @param WP_Post $post Current post.
134 *
135 * @return string
136 */
137 public function add_imported_tour_badge($post_states_html, $post_states, $post)
138 {
139 if ('wpvr_item' !== $post->post_type || 'yes' !== get_post_meta($post->ID, '_wpvr_imported_tour', true)) {
140 return $post_states_html;
141 }
142
143 $imported_at = (int) get_post_meta($post->ID, '_wpvr_imported_at', true);
144 if (!$imported_at) {
145 $imported_at = (int) get_post_time('U', true, $post);
146 }
147
148 if (time() >= $imported_at + (7 * DAY_IN_SECONDS)) {
149 return $post_states_html;
150 }
151
152 return '<span class="wpvr-imported-tour-badge">' . esc_html__('Imported', 'wpvr') . '</span>' . $post_states_html;
153 }
154
155 /**
156 * Remove the Imported badge after an imported tour is updated.
157 *
158 * @param int $post_id Post ID.
159 * @param WP_Post $post Updated post.
160 *
161 * @return void
162 */
163 public function remove_imported_tour_badge($post_id, $post)
164 {
165 if ('wpvr_item' !== $post->post_type) {
166 return;
167 }
168
169 delete_post_meta($post_id, '_wpvr_imported_tour');
170 delete_post_meta($post_id, '_wpvr_imported_at');
171 }
172
173 /**
174 * Register the stylesheets for the admin area.
175 *
176 * @since 8.0.0
177 */
178 public function enqueue_styles() {
179
180 /**
181 * This function is provided for demonstration purposes only.
182 *
183 * An instance of this class should be passed to the run() function
184 * defined in Wpvr_Loader as all of the hooks are defined
185 * in that particular class.
186 *
187 * The Wpvr_Loader will then create the relationship
188 * between the defined hooks and the functions defined in this
189 * class.
190 */
191 $screen = get_current_screen();
192
193
194 if ($screen->id == "toplevel_page_wpvr" || $screen->id == "wp-vr_page_wpvr-setting") {
195 wp_enqueue_style('materialize-css', plugin_dir_url(__FILE__) . 'css/materialize.min.css', array(), $this->version, 'all');
196 wp_enqueue_style('materialize-icons', plugin_dir_url(__FILE__) . 'lib/materializeicon.css', array(), $this->version, 'all');
197 wp_enqueue_style('owl-css', plugin_dir_url(__FILE__) . 'css/owl.carousel.css', array(), $this->version, 'all');
198 wp_enqueue_style($this->plugin_name, plugin_dir_url(__FILE__) . 'css/wpvr-admin.css', array(), $this->version, 'all');
199 wp_enqueue_style('wpvr-rtl', plugin_dir_url(__FILE__) . 'css/wpvr-admin-rtl.css', array(), $this->version, 'all');
200 }
201
202 if ($screen->id == "edit-wpvr_item") {
203 $listing_style_path = plugin_dir_path(__FILE__) . 'css/wpvr-admin-post-type.css';
204 $listing_style_version = file_exists($listing_style_path) ? filemtime($listing_style_path) : $this->version;
205 wp_enqueue_style($this->plugin_name, plugin_dir_url(__FILE__) . 'css/wpvr-admin-post-type.css', array(), $listing_style_version, 'all');
206 }
207
208 if ($screen->id == "wpvr_item") {
209 wp_enqueue_style($this->plugin_name . 'fontawesome', plugin_dir_url(__FILE__) . 'lib/fontawesome/css/all.css', array(), $this->version, 'all');
210 wp_enqueue_style('icon-picker-css', plugin_dir_url(__FILE__) . 'css/jquery.fonticonpicker.min.css', array(), $this->version, 'all');
211 wp_enqueue_style('icon-picker-css-theme', plugin_dir_url(__FILE__) . 'css/jquery.fonticonpicker.grey.min.css', array(), $this->version, 'all');
212 wp_enqueue_style('owl-css', plugin_dir_url(__FILE__) . 'css/owl.carousel.css', array(), $this->version, 'all');
213 wp_enqueue_style('panellium-css', plugin_dir_url(__FILE__) . 'lib/pannellum/src/css/pannellum.css', array(), true);
214 wp_enqueue_style('videojs-css', plugin_dir_url(__FILE__) . 'lib/pannellum/src/css/video-js.css', array(), true);
215 wp_enqueue_style($this->plugin_name, plugin_dir_url(__FILE__) . 'css/wpvr-admin.css', array(), $this->version, 'all');
216 wp_enqueue_style('wpvr-image-resize-warning', plugin_dir_url(__FILE__) . 'css/wpvr-image-resize-warning.css', array(), filemtime(plugin_dir_path(__FILE__) . 'css/wpvr-image-resize-warning.css'), 'all');
217 wp_enqueue_style('wpvr-rtl', plugin_dir_url(__FILE__) . 'css/wpvr-admin-rtl.css', array(), $this->version, 'all');
218 wp_enqueue_style('summernote', plugin_dir_url(__FILE__) . 'lib/summernote/summernote-lite.min.css', array(), $this->version, 'all');
219
220 if (isset($_REQUEST['wpvr-guide-tour']) && $_REQUEST['wpvr-guide-tour'] == 1) {
221 wp_enqueue_style($this->plugin_name . '-shepherd-css', plugin_dir_url(__FILE__) . 'lib/shepherd/css/shepherd-theme-arrows-plain-buttons.css', false, $this->version);
222 wp_enqueue_style($this->plugin_name . '-tour-css', plugin_dir_url(__FILE__) . 'lib/shepherd/css/wpvr-tour-guide.min.css', false, $this->version);
223 }
224 }
225
226 if ($screen->id == "wp-vr_page_wpvr-setup-wizard") {
227 wp_enqueue_style($this->plugin_name, plugin_dir_url(__FILE__) . 'css/wpvr-admin2.css', array(), $this->version, 'all');
228 wp_enqueue_style('wpvr-admin2-rtl', plugin_dir_url(__FILE__) . 'css/wpvr-admin2-rtl.css', array(), $this->version, 'all');
229 }
230
231 if ($screen->id == "dashboard_page_rex-wpvr-setup-wizard") {
232 wp_enqueue_style($this->plugin_name, plugin_dir_url(__FILE__) . 'css/style.css', array(), $this->version, 'all');
233 }
234 }
235
236
237 /**
238 * Register the JavaScript for the admin area.
239 *
240 * @since 8.0.0
241 */
242 public function enqueue_scripts() {
243
244 /**
245 * This function is provided for demonstration purposes only.
246 *
247 * An instance of this class should be passed to the run() function
248 * defined in Wpvr_Loader as all of the hooks are defined
249 * in that particular class.
250 *
251 * The Wpvr_Loader will then create the relationship
252 * between the defined hooks and the functions defined in this
253 * class.
254 */
255
256 $wpvr_list = array();
257 $wpvr_list[] = array('value' => 0, 'label' => 'None');
258 $args = array(
259 'numberposts' => -1,
260 'post_type' => 'wpvr_item'
261 );
262
263 $wpvr_posts = get_posts($args);
264 foreach ($wpvr_posts as $wpvr_post) {
265 $title = $wpvr_post->ID . ' : ' . $wpvr_post->post_title;
266 $wpvr_list[] = array( 'value'=>$wpvr_post->ID,'label'=> $title);
267 }
268
269 wp_enqueue_script('wp-api');
270 wp_enqueue_media();
271
272 $asset_url = apply_filters('change_asset_url', plugin_dir_url(__FILE__));
273 $admin_script_path = plugin_dir_path(__FILE__) . 'js/wpvr-admin.js';
274
275 if (defined('WPVR_PRO_PLUGIN_DIR_URL') && defined('WPVR_PRO_PLUGIN_DIR_PATH') && $asset_url === WPVR_PRO_PLUGIN_DIR_URL . 'admin/') {
276 $admin_script_path = WPVR_PRO_PLUGIN_DIR_PATH . 'admin/js/wpvr-admin.js';
277 }
278
279 wp_enqueue_script('wp-api');
280 $adscreen = get_current_screen();
281 wp_enqueue_media();
282 if ($adscreen->id == "wpvr_item" || $adscreen->id == "toplevel_page_wpvr" || $adscreen->id == "wp-vr_page_wpvr-setting" || $adscreen->id == "edit-wpvr_item") {
283 wp_enqueue_script('summernote', $asset_url . 'lib/summernote/summernote-lite.min.js', array('jquery'), true);
284 wp_enqueue_script('wpvr-icon-picker', $asset_url . 'lib/jquery.fonticonpicker.min.js', array(), true);
285 wp_enqueue_script('panellium-js', $asset_url . 'lib/pannellum/src/js/pannellum.js', array(), true);
286 wp_enqueue_script('panelliumlib-js', $asset_url . 'lib/pannellum/src/js/libpannellum.js', array(), true);
287 wp_enqueue_script('videojs-js', $asset_url . 'js/video.js', array('jquery'), true);
288 wp_enqueue_script('panelliumvid-js', $asset_url . 'lib/pannellum/src/js/videojs-pannellum-plugin.js', array(), true);
289 wp_enqueue_script('jquery-repeater', $asset_url . 'js/jquery.repeater.min.js', array('jquery'), true);
290 wp_enqueue_script('icon-picker', $asset_url . 'lib/jquery.fonticonpicker.min.js', array(), true);
291 wp_enqueue_script('owl', $asset_url . 'js/owl.carousel.js', array('jquery'), false);
292 wp_enqueue_script('wpvr-image-resize-warning', plugin_dir_url(__FILE__) . 'js/wpvr-image-resize-warning.js', array('jquery'), filemtime(plugin_dir_path(__FILE__) . 'js/wpvr-image-resize-warning.js'), true);
293 wp_enqueue_script($this->plugin_name, $asset_url . 'js/wpvr-admin.js', array('jquery', 'wpvr-image-resize-warning'), filemtime($admin_script_path), true);
294 wp_localize_script($this->plugin_name, 'wpvr_localize', array(
295 'WriteYourCssHere' => __('Write your css here', 'wpvr'),
296 'VideoTourNotice' => __('Turning On The Video Option Will Erase Your Virtual Tour Data. Are You Sure?', 'wpvr'),
297 'StreetViewNotice' => __('Turning On The StreetView Option Will Erase Your Virtual Tour Data. Are You Sure?', 'wpvr'),
298 'AddingHotspotsOnScene' => __('Adding Hotspots on Scene', 'wpvr'),
299 'WPVR_ASSET_PATH' => WPVR_ASSET_PATH,
300 ));
301 if (isset($_REQUEST['wpvr-guide-tour']) && $_REQUEST['wpvr-guide-tour'] == 1) {
302 wp_enqueue_script($this->plugin_name . '-tether-js', plugin_dir_url(__FILE__) . 'lib/shepherd/tether/tether.js', $this->version, true);
303 wp_enqueue_script($this->plugin_name . '-shepherd-js', plugin_dir_url(__FILE__) . 'lib/shepherd/tether-shepherd/shepherd.js', array($this->plugin_name . '-tether-js'), $this->version, true);
304 wp_enqueue_script($this->plugin_name . '-tour-guide', plugin_dir_url(__FILE__) . 'js/wpvr-tour-guide.js', array('jquery', $this->plugin_name . '-tether-js'), $this->version, true);
305 $tour_guide_translation = new WPVR_Tour_Guide_Translation();
306
307 wp_localize_script($this->plugin_name . '-tour-guide', 'wpvr_tour_guide_obj', array(
308 'Tour_Guide_Translation' => $tour_guide_translation->get_translatable_string(),
309 'step1_bg_image' => plugins_url('admin/icon/first-step-bg.png', WPVR_FILE),
310 'next_button_arrow' => plugins_url('admin/icon/next-button-arrow.png', WPVR_FILE),
311 ));
312 }
313
314 wp_localize_script($this->plugin_name, 'wpvr_obj', array(
315 'ajaxurl' => admin_url('admin-ajax.php'),
316 'ajax_nonce' => wp_create_nonce('wpvr'),
317 'translated_languages' => $this->get_translated_languages(),
318 'site_language' => get_locale(),
319 'successfully_updated' => __('Successfully Updated', 'wpvr'),
320 'importing_text' => __('Importing...', 'wpvr'),
321 'import_text' => __('Import Now', 'wpvr'),
322 'admin_url' => admin_url(),
323 'is_wpvr_pro_active' => apply_filters('is_wpvr_pro_active', false),
324 'is_wpvr_license_valid' => get_option('wpvr_edd_license_status', '') === 'valid',
325 'published_text' => __('Published', 'wpvr'),
326 'dis_on_hover' => get_option('dis_on_hover') === 'true' ? true : false,
327 'mobile_hotspot_tip' => get_option('wpvr_mobile_hotspot_tip') === 'true' ? true : false,
328 'image_resize_warning' => array(
329 'heading' => __('Keep this panorama in High Resolution', 'wpvr'),
330 'scaled_message' => __('By default, a resized version is created while the original image is still available.', 'wpvr'),
331 'disable_handler' => __('Disable WordPress Large Image Handler on WP VR for future uploads', 'wpvr'),
332 'high_resolution_note' => __('*Note: Turn this on to use the high-resolution image.', 'wpvr'),
333 'close' => __('Close', 'wpvr'),
334 'can_manage_settings' => current_user_can('manage_options'),
335 'setting_enabled' => get_option('high_res_image') === 'true',
336 ),
337 ));
338 }
339
340 if ($adscreen->id == "toplevel_page_wpvr" || $adscreen->id == "wp-vr_page_wpvr-setting") {
341 wp_enqueue_script('materialize-js', $asset_url . 'js/materialize.min.js', array('jquery'), $this->version, false);
342 }
343
344 if ($adscreen->id == "wpvr_item") {
345 wp_enqueue_script($this->plugin_name . '-shortcode', plugin_dir_url(__FILE__) . 'js/wpvr-shortcode.js', array('jquery'), $this->version, true);
346 }
347
348 $is_wpvr_screen = false;
349 if ( isset( $adscreen->id ) ) {
350 $is_wpvr_screen = (
351 $adscreen->id === 'wpvr_item' ||
352 $adscreen->id === 'edit-wpvr_item' ||
353 $adscreen->id === 'toplevel_page_wpvr' ||
354 $adscreen->id === 'wp-vr_page_wpvr-setting' ||
355 false !== strpos( $adscreen->id, 'wpvr' ) ||
356 false !== strpos( $adscreen->id, 'wp-vr' ) ||
357 ( isset( $adscreen->post_type ) && 'wpvr_item' === $adscreen->post_type )
358 );
359 }
360
361 if ( $is_wpvr_screen ) {
362 wp_enqueue_script('owl-js', plugin_dir_url(__FILE__) . 'js/owl.carousel.js', array('jquery'), false);
363 wp_enqueue_script('wpvr-global', $asset_url . 'js/wpvr-global.js', array('jquery'), $this->version, false);
364
365 $admin_user = wp_get_current_user();
366 $admin_name = $admin_user->display_name ?? '';
367
368 wp_localize_script('wpvr-global', 'wpvr_global_obj', array(
369 'ajaxurl' => admin_url('admin-ajax.php'),
370 'site_url' => site_url() . '/wp-json/',
371 'ajax_nonce' => wp_create_nonce('wpvr'),
372 'user_information' => $this->get_logged_in_user_information(),
373 'is_wpvr_active' => is_plugin_active('wpvr-pro/wpvr-pro.php'),
374 'admin_name' => $admin_name,
375 'url_info' => array(
376 'admin_url' => admin_url(),
377 'screen' => $adscreen->action,
378 'url' => isset( $_SERVER['PHP_SELF'] ) ? sanitize_text_field( wp_unslash( $_SERVER['PHP_SELF'] ) ) : '',
379 'param' => $_GET,
380 ),
381 'active_tab_url' => admin_url('post-new.php?post_type=wpvr_item&active_tab=scene'),
382 'hotspot_warning_text' => __('Please upload a scene before proceeding to set hotspot!', 'wpvr'),
383 'negative_number_warning_text' =>__('Negative numbers are not allowed!', 'wpvr'),
384 ));
385
386 wp_localize_script('wpvr-global', 'wpvr_id_options', $wpvr_list);
387 }
388 }
389
390 /**
391 * Retrieve the currently logged-in user's email and name.
392 *
393 * @since 8.4.10
394 *
395 * @return array An associative array containing the logged-in user's email and name.
396 */
397 public function get_logged_in_user_information(): array
398 {
399 $admin_user = wp_get_current_user();
400 return array(
401 'email' => !empty( $admin_user->user_email ) ? $admin_user->user_email : '',
402 'name' => !empty( $admin_user->display_name ) ? $admin_user->display_name : '',
403 );
404 }
405
406
407 /**
408 * Set Preview and Setup custom metabox of this plugin
409 *
410 * @since 8.0.0
411 */
412 public function set_custom_meta_box() {
413 $this->setup_metabox = new WPVR_Setup_Meta_Box('setup', __('Setup', 'wpvr'), 'wpvr_item', 'normal', 'high');
414
415 $this->preview_metabox = new WPVR_Tour_Preview($this->post_type . '_builder__box', __('Tour Preview', 'wpvr'), $this->post_type, 'side', 'high');
416
417 $this->checklist_metabox = new WPVR_Tour_Checklist_Meta_Box($this->post_type . '_tour_checklist__box', __('Checklist', 'wpvr'), $this->post_type, 'side', 'high');
418
419 }
420
421
422 /**
423 * Plugin action links
424 *
425 * @param $actions || $links
426 * @return array
427 * @since 8.0.0
428 */
429 public function plugin_action_links_wpvr($actions)
430 {
431 $actions['get_started'] = sprintf(
432 '<a href="%s">%s</a>',
433 esc_url(admin_url('admin.php?page=wpvr')),
434 esc_html__('Get Started', 'wpvr')
435 );
436 $actions['documentation'] = sprintf(
437 '<a href="%s" target="_blank">%s</a>',
438 esc_url('https://rextheme.com/docs-category/wp-vr/'),
439 esc_html__('Documentation', 'wpvr')
440 );
441
442 if (!apply_filters('is_wpvr_pro_active', false)) {
443 $actions['go-pro'] = sprintf(
444 '<a href="%s" target="_blank" style="color: #201cfe; font-weight: bold;">%s</a>',
445 esc_url('https://rextheme.com/wpvr/wpvr-pricing/'),
446 esc_html__('Go Pro', 'wpvr')
447 );
448 }
449
450 return $actions;
451 }
452
453 /**
454 * Rollback execution
455 */
456 public function trigger_rollback()
457 {
458 if (!current_user_can('update_plugins') && !current_user_can('install_plugins')) {
459 return false;
460 }
461 $version = isset($_GET['wpvr_version']) ? sanitize_text_field(wp_unslash($_GET['wpvr_version'])) : '';
462 if ($version) {
463 check_admin_referer('wpvr_rollback', 'wpvr_rollback');
464 $plugin_slug = 'wpvr';
465 $rollback = new WPVR_Rollback(
466 [
467 'version' => $version,
468 'plugin_name' => 'wpvr',
469 'plugin_slug' => $plugin_slug,
470 'package_url' => sprintf('https://downloads.wordpress.org/plugin/%s.%s.zip', $plugin_slug, $version),
471 ]
472 );
473
474 $rollback->run();
475 }
476 }
477
478 /**
479 * Floor plan image Display
480 * Display Pro feature demo in free user
481 * @return void
482 */
483
484 public function floor_plan_image_show_for_free_user() {
485 if (!is_plugin_active('wpvr-pro/wpvr-pro.php')) {
486
487 ?>
488 <div class="rex-pano-tab floor-plan" id="floorPlan">
489
490 <img loading="lazy" src="<?php echo esc_url( WPVR_PLUGIN_DIR_URL . 'images/floor-plan-demo.png' ); ?>" alt="icon" />
491 </div>
492 <?php
493 }
494 }
495
496 /**
497 * Background Tour image Display
498 * Display Pro feature demo in free user
499 * @return void
500 */
501 public function background_tour_image_show_for_free_user() {
502 if (!is_plugin_active('wpvr-pro/wpvr-pro.php')) {
503
504 ?>
505 <div class="rex-pano-tab background-tour" id="backgroundTour">
506
507 <!-- <img src="--><?php //= WPVR_PLUGIN_DIR_URL . 'images/floor-plan-demo.png'
508 ?><!--" alt="icon" />-->
509 </div>
510 <?php
511 }
512 }
513 /**
514 * Street View image Display
515 * Display Pro feature demo in free user
516 * @return void
517 */
518
519 public function street_view_image_show_for_free_user() {
520 if (!is_plugin_active('wpvr-pro/wpvr-pro.php')) {
521
522 ?>
523 <div class="rex-pano-tab streetview" id="streetview">
524 <!-- <img src="--><?php //= WPVR_PLUGIN_DIR_URL . 'images/floor-plan-demo.png'
525 ?><!--" alt="icon" />-->
526 </div>
527 <?php
528 }
529 }
530
531 public function scene_pro_image_show_for_free_user($pano_scene) {
532 if (!is_plugin_active('wpvr-pro/wpvr-pro.php')) {
533
534 ?>
535 <img loading="lazy" src="<?php echo esc_url( WPVR_PLUGIN_DIR_URL . 'images/scene-pro-feature.png' ); ?>" alt="icon" />
536 <?php
537 }
538 }
539
540
541 public function empty_scene_pro_image_show_for_free_user() {
542 if (!is_plugin_active('wpvr-pro/wpvr-pro.php')) {
543 echo '<img loading="lazy" src="' . esc_url(WPVR_PLUGIN_DIR_URL . 'images/scene-pro-feature.png') . '" alt="WPVR Pro Feature" />';
544 }
545 }
546
547 public function show_review_request_markups() {
548 $show_review_request = get_option('wpvr_feed_review_request');
549 if (empty($show_review_request)) {
550 $data = array(
551 'show' => true,
552 'time' => '',
553 'frequency' => 'immediate',
554 );
555 update_option('wpvr_feed_review_request', $data);
556 }
557 }
558
559 public function wpvr_trigger_based_review_helper() {
560 $show_review_request = get_option('wpvr_feed_review_request');
561 $number_of_published_tours = $this->wpvr_get_total_published_tours();
562 if (!empty($show_review_request) && isset($show_review_request['show']) && $show_review_request['show']) {
563
564 if (isset($show_review_request['frequency']) && $number_of_published_tours > 1) {
565 if ($show_review_request['frequency'] == 'immediate') {
566 add_action('admin_notices', array($this, 'wpvr_generate_review_request_section'));
567 } elseif ($show_review_request['frequency'] == 'one_week') {
568 $last_shown_date = $show_review_request['time'];
569 $current_date = time();
570 $current_date = new DateTime(gmdate('Y-m-d', $current_date));
571 $last_shown_date = new DateTime(gmdate('Y-m-d', $last_shown_date));
572 $date_diff = $last_shown_date->diff($current_date);
573
574 if ($date_diff->d > 7) {
575 add_action('admin_notices', array($this, 'wpvr_generate_review_request_section'));
576 }
577 }
578 }
579 }
580 }
581
582 public function wpvr_generate_review_request_section() {
583 $screen = get_current_screen();
584
585 $promotional_notice_pages = [
586 'dashboard',
587 'plugins',
588 'wpvr_item',
589 'edit-wpvr_item',
590 'toplevel_page_wpvr',
591 'wp-vr_page_wpvr-setup-wizard'
592 ];
593
594 // Only proceed if the current screen ID matches the allowed pages.
595 if (!in_array($screen->id, $promotional_notice_pages)) {
596 return;
597 }
598
599 require_once plugin_dir_path(__FILE__) . 'partials/wpvr-review-request-body-content.php';
600 }
601
602 /**
603 * Get translated languages
604 *
605 * @return array
606 * @since 8.5.21
607 */
608 public function get_translated_languages(){
609 $language_mapping = [
610 'ar' => [ // Arabic
611 'Publish' => 'نشر', // nashr
612 'Update' => 'تحديث' // tahdith
613 ],
614 'pt_PT' => [ // Portuguese (Portugal)
615 'Publish' => 'Publicar',
616 'Update' => 'Atualizar'
617 ],
618 'es_ES' => [ // Spanish (Spain)
619 'Publish' => 'Publicar',
620 'Update' => 'Actualizar'
621 ],
622 'he_IL' => [ // Hebrew (Israel)
623 'Publish' => 'לפרסם', // lefarsem
624 'Update' => 'לעדכן' // le'adken
625 ],
626 'af' => [ // Afrikaans
627 'Publish' => 'Publiseer',
628 'Update' => 'Opdateer'
629 ],
630 'cs_CZ' => [ // Czech (Czech Republic)
631 'Publish' => 'Publikovat',
632 'Update' => 'Aktualizovat'
633 ],
634 'da_DK' => [ // Danish (Denmark)
635 'Publish' => 'Udgiv',
636 'Update' => 'Opdater'
637 ],
638 'de_DE' => [ // German (Germany)
639 'Publish' => 'Veröffentlichen',
640 'Update' => 'Aktualisieren'
641 ],
642 'fi' => [ // Finnish
643 'Publish' => 'Julkaise',
644 'Update' => 'Päivitä'
645 ],
646 'hr' => [ // Croatian
647 'Publish' => 'Objavi',
648 'Update' => 'Ažuriraj'
649 ],
650 'it_IT' => [ // Italian (Italy)
651 'Publish' => 'Pubblica',
652 'Update' => 'Aggiorna'
653 ],
654 'ja' => [ // Japanese
655 'Publish' => '�
656 �開',
657 'Update' => '更新'
658 ],
659 'nl_NL' => [ // Dutch (Netherlands)
660 'Publish' => 'Publiceren',
661 'Update' => 'Updaten'
662 ],
663 'pl_PL' => [ // Polish (Poland)
664 'Publish' => 'Opublikuj',
665 'Update' => 'Aktualizuj'
666 ],
667 'ru_RU' => [ // Russian (Russia)
668 'Publish' => 'Опубликовать',
669 'Update' => 'Обновить'
670 ],
671 'sv_SE' => [ // Swedish (Sweden)
672 'Publish' => 'Publicera',
673 'Update' => 'Uppdatera'
674 ],
675 'fr_FR' => [ // French (France)
676 'Publish' => 'Publier',
677 'Update' => 'Mettre à jour'
678 ],
679 'fr_CA' => [ // French (Canada)
680 'Publish' => 'Publier',
681 'Update' => 'Mettre à jour',
682 ],
683 'fr_BE' => [ // French (Belgium)
684 'Publish' => 'Publier',
685 'Update' => 'Mettre à jour',
686 ],
687 'fr_CH' => [ // Switzerland
688 'Publish' => 'Publier',
689 'Update' => 'Mettre à jour',
690 ],
691 'fr_LU' => [ // Luxembourg
692 'Publish' => 'Publier',
693 'Update' => 'Mettre à jour',
694 ],
695 'fr_MC' => [ // Monaco
696 'Publish' => 'Publier',
697 'Update' => 'Mettre à jour',
698 ],
699 'fr_CM' => [ // Cameroon
700 'Publish' => 'Publier',
701 'Update' => 'Mettre à jour',
702 ],
703 'fr_DZ' => [ // Algeria
704 'Publish' => 'Publier',
705 'Update' => 'Mettre à jour',
706 ],
707 'fr_MA' => [ // Morocco
708 'Publish' => 'Publier',
709 'Update' => 'Mettre à jour',
710 ],
711 'fr_TN' => [ // Tunisia
712 'Publish' => 'Publier',
713 'Update' => 'Mettre à jour',
714 ],
715 'fr_SN' => [ // Senegal
716 'Publish' => 'Publier',
717 'Update' => 'Mettre à jour',
718 ],
719 'fr_HT' => [ // Haiti
720 'Publish' => 'Publier',
721 'Update' => 'Mettre à jour',
722 ],
723 'fr_RW' => [ // Rwanda
724 'Publish' => 'Publier',
725 'Update' => 'Mettre à jour',
726 ],
727 'fr_CD' => [ // DR Congo
728 'Publish' => 'Publier',
729 'Update' => 'Mettre à jour',
730 ],
731 'fr_CI' => [ // Côte d’Ivoire
732 'Publish' => 'Publier',
733 'Update' => 'Mettre à jour',
734 ],
735 ];
736
737 return $language_mapping;
738 }
739
740
741 /**
742 * Add import button to the WPVR All Tours page
743 *
744 * @since 8.5.22
745 */
746 public function add_import_button() {
747 $screen = get_current_screen();
748 $status = get_option('wpvr_edd_license_status');
749 $is_pro_available = apply_filters('is_wpvr_pro_active', false) && $status === 'valid';
750
751 // Only add button on the WPVR Tours admin page
752 if ($screen && property_exists($screen, 'id') && ($screen->id === 'edit-wpvr_item')) {
753 ?>
754 <script type="text/javascript">
755 jQuery(document).ready(function($) {
756
757 // Check if user has WPVR Pro
758 var isProUser = <?php echo wp_json_encode($is_pro_available); ?>;
759
760 // Add the Import WPVR Tour button
761 var importButton = $('<a href="#" class="page-title-action wpvr-import-button"><?php echo esc_js( esc_html__( 'Import Tour', 'wpvr' ) ); ?></a>');
762 $('.wrap .page-title-action').after(importButton);
763
764 // If Free Version, add 'Pro' label
765 if (!isProUser) {
766 importButton
767 .addClass('wpvr-import-button--locked')
768 .attr({
769 'aria-disabled': 'true',
770 'aria-haspopup': 'dialog'
771 })
772 .append("<span class='is-pro' aria-hidden='true'>Pro</span>");
773 }
774
775 // If button wasn't added, try alternative placement
776 if ($('.wpvr-import-button').length === 0) {
777 $('.wrap h1.wp-heading-inline').after(importButton);
778 }
779
780 // Add the WPVR Import Form (hidden by default)
781 var importForm = `
782 <div id="wpvr-import-template-area">
783 <div id="wpvr-import-template-title">Choose a .zip archive of a WPVR tour and add it to your website.</div>
784 <form id="wpvr-import-template-form" method="post" action="<?php echo esc_url(admin_url('admin-ajax.php')); ?>" enctype="multipart/form-data">
785 <input type="hidden" name="action" value="wpvr_import_tour">
786 <fieldset id="wpvr-import-template-form-inputs">
787 <input type="file" name="wpvr_import_tour_file" accept=".zip" required>
788 <input id="wpvr-import-template-action" type="button" class="button button-primary" value="${wpvr_obj?.import_text}">
789 </fieldset>
790 </form>
791 </div>
792 `;
793
794 // Append the form after the Import button
795 $('.wpvr-import-button').after(importForm);
796
797 // Toggle form visibility on button click
798 $(document).on('click', '.wpvr-import-button', function(e) {
799 e.preventDefault();
800 if (!isProUser) {
801 // Open CRO Modal (Pro Upgrade)
802 $("#wpvr_premium_feature_popup").show();
803 } else {
804 // Open WPVR Import Form
805 $('#wpvr-import-template-area').toggle();
806 }
807 });
808
809 // Close CRO Modal
810 $(document).on("click", "#wpvr_premium_feature_close", function () {
811 $("#wpvr_premium_feature_popup").hide();
812 });
813
814 var $importButton = $('#wpvr-import-template-action');
815 var $fileInput = $('input[name="wpvr_import_tour_file"]');
816
817 // Initially disable the import button
818 $importButton.prop('disabled', true);
819
820 // Enable button when a file is selected
821 $fileInput.on('change', function() {
822 if ($(this).val()) {
823 $importButton.prop('disabled', false);
824 } else {
825 $importButton.prop('disabled', true);
826 }
827 });
828 });
829 </script>
830 <?php
831 }
832 }
833
834 /**
835 * Enqueue deactivation sub-reason JS on plugins.php only, after SDK modal (priority 99).
836 *
837 * @return void
838 */
839 public function enqueue_deactivation_scripts() {
840 global $pagenow;
841 if ( 'plugins.php' !== $pagenow ) {
842 return;
843 }
844 wp_enqueue_script(
845 'wpvr-deactivation',
846 plugin_dir_url( __FILE__ ) . 'js/wpvr-deactivation.js',
847 array( 'jquery' ),
848 $this->version,
849 true
850 );
851 }
852
853 /**
854 * Get total published tours
855 *
856 * @return int
857 * @since 8.5.43
858 */
859 public function wpvr_get_total_published_tours(){
860 $args = array(
861 'post_type' => 'wpvr_item',
862 'post_status' => 'publish',
863 'posts_per_page' => -1,
864 'fields' => 'ids',
865 );
866
867 $query = new WP_Query( $args );
868 return $query->found_posts;
869 }
870
871 }
872