plugin_name = $plugin_name; $this->version = $version; $this->loader = $loader; $this->settings = $this->get_settings(); $this->loader->add_action( 'save_post', $this, 'record_first_model', 20, 2 ); $this->loader->add_action( 'admin_notices', $this, 'show_review_notice' ); $this->loader->add_action( 'admin_post_threedvieweronline_review', $this, 'handle_review_choice' ); $this->loader->add_action( 'wp_ajax_threedvieweronline_review', $this, 'handle_review_choice' ); } /** * Register the JavaScript & CSS for the admin area. * * @since 1.0.0 */ /** Return whether this content has a configured model, without loading it. */ private function has_configured_model( $post ) { if ( 'product' === $post->post_type && '' !== threedvieweronline_url( get_post_meta( $post->ID, 'threed_model_url', true ) ) ) { return true; } $pending = parse_blocks( $post->post_content ); while ( $pending ) { $block = array_pop( $pending ); if ( 'dvieweronline/dvieweronline-iframe' === $block['blockName'] && '' !== threedvieweronline_url( $block['attrs']['iframeSrc'] ?? '' ) ) { return true; } foreach ( $block['innerBlocks'] ?? array() as $child ) { $pending[] = $child; } } if ( preg_match_all( '/' . get_shortcode_regex( array( '3Dvo-model' ) ) . '/s', $post->post_content, $matches, PREG_SET_ORDER ) ) { foreach ( $matches as $match ) { if ( '[' === $match[1] && ']' === $match[6] ) { continue; // Escaped shortcode, displayed as text. } $atts = shortcode_parse_atts( $match[3] ); if ( is_array( $atts ) && '' !== threedvieweronline_url( $atts['url'] ?? '' ) ) { return true; } } } return false; } /** Start the clock only after published content is configured. */ public function record_first_model( $post_id, $post ) { if ( wp_is_post_revision( $post_id ) || wp_is_post_autosave( $post_id ) || ! in_array( $post->post_type, array( 'product', 'page', 'post' ), true ) || 'publish' !== $post->post_status ) { return; } if ( $this->has_configured_model( $post ) ) { add_option( 'threedvieweronline_first_model', time(), '', false ); update_option( 'threedvieweronline_review_post', $post_id, false ); } } /** Local, per-administrator choices; no tracking request is sent. */ public function handle_review_choice() { if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'You do not have permission to do this.', '3dvieweronline-wp' ) ); } if ( wp_doing_ajax() ) { check_ajax_referer( 'threedvieweronline_review', '_wpnonce' ); } else { check_admin_referer( 'threedvieweronline_review' ); } $choice = isset( $_POST['choice'] ) && is_string( $_POST['choice'] ) ? sanitize_key( wp_unslash( $_POST['choice'] ) ) : ''; if ( ! in_array( $choice, array( 'review', 'later', 'dismiss' ), true ) ) { wp_die( esc_html__( 'Invalid review choice.', '3dvieweronline-wp' ) ); } update_user_meta( get_current_user_id(), 'threedvieweronline_review_after', 'later' === $choice ? time() + 30 * DAY_IN_SECONDS : -1 ); if ( wp_doing_ajax() ) { wp_send_json_success(); } wp_safe_redirect( admin_url( 'admin.php?page=threed-setting' ) ); exit; } public function show_review_notice() { if ( ! current_user_can( 'manage_options' ) ) { return; } $screen = get_current_screen(); if ( ! $screen || ( 'toplevel_page_threed-setting' !== $screen->id && ( 'post' !== $screen->base || ! in_array( $screen->post_type, array( 'product', 'page', 'post' ), true ) ) ) ) { return; } $first = (int) get_option( 'threedvieweronline_first_model', 0 ); $after = (int) get_user_meta( get_current_user_id(), 'threedvieweronline_review_after', true ); $post = get_post( (int) get_option( 'threedvieweronline_review_post', 0 ) ); if ( ! $first || time() < $first + DAY_IN_SECONDS || -1 === $after || time() < $after || ! $post || 'publish' !== $post->post_status || ! $this->has_configured_model( $post ) ) { return; } if ( 'toplevel_page_threed-setting' !== $screen->id ) { $current = get_post(); if ( ! $current || ! $this->has_configured_model( $current ) ) { return; } } ?>

base && in_array( $screen->post_type, array( 'page', 'post' ), true ) ) { wp_enqueue_script( $this->plugin_name . '-common-js', plugins_url( '/admin/js/threedvieweronline-common-admin.js', THREED_PLUGIN_FILE ), array( 'jquery' ), $this->version, true ); wp_enqueue_style( $this->plugin_name . '-common-style', plugins_url( '/admin/css/threedvieweronline-common-admin.css', THREED_PLUGIN_FILE ), array(), $this->version ); } if ( ! $screen || ( 'product' !== $screen->post_type && 'toplevel_page_threed-setting' !== $screen->id ) ) { return; } wp_enqueue_script( $this->plugin_name . '-common-js', plugins_url( '/admin/js/threedvieweronline-common-admin.js', THREED_PLUGIN_FILE ), array( 'jquery' ), $this->version, true ); wp_enqueue_style( $this->plugin_name . '-common-style', plugins_url( '/admin/css/threedvieweronline-common-admin.css', THREED_PLUGIN_FILE ), array(), $this->version ); if ( 'toplevel_page_threed-setting' === $screen->id ) { $this->enqueue_styles(); $this->enqueue_scripts(); } } /** * Enque the styles. * * @since 1.0.0 */ public function enqueue_styles() { wp_enqueue_style( $this->plugin_name . '-font-awesome', plugins_url( '/admin/css/font-awesome/css/font-awesome.min.css', THREED_PLUGIN_FILE ), array(), $this->version, 'all' ); wp_enqueue_style( $this->plugin_name, plugins_url( '/admin/css/threedvieweronline-iframe-admin.css', THREED_PLUGIN_FILE ), array(), $this->version, 'all' ); } /** * Enque the scripts. * * @since 1.0.0 */ public function enqueue_scripts() { wp_enqueue_media(); wp_enqueue_script( $this->plugin_name, plugins_url( '/admin/js/threedvieweronline-iframe-admin.js', THREED_PLUGIN_FILE ), array( 'jquery' ), $this->version, false ); } /** * Enquees block assets. * * @since 1.0.0 */ public function register_blocks() { wp_register_script( $this->plugin_name . '-blocks', plugins_url( '/dist/blocks.build.js', THREED_PLUGIN_FILE ), array( 'wp-blocks', 'wp-i18n', 'wp-element', 'wp-block-editor', 'wp-components' ), $this->version, true ); wp_set_script_translations( $this->plugin_name . '-blocks', '3dvieweronline-wp', THREED_PLUGIN_DIR . '/languages' ); wp_register_style( $this->plugin_name . '-blocks-style', plugins_url( '/dist/blocks.style.build.css', THREED_PLUGIN_FILE ), array(), $this->version ); wp_register_style( $this->plugin_name . '-editor', plugins_url( '/dist/blocks.editor.build.css', THREED_PLUGIN_FILE ), array(), $this->version ); register_block_type( THREED_PLUGIN_DIR . '/blocks/iframe' ); register_block_type( THREED_PLUGIN_DIR . '/blocks/product', array( 'render_callback' => array( $this, 'render_product_block' ) ) ); } public function render_product_block( $attributes, $content, $block ) { if ( ! function_exists( 'wc_get_product' ) ) { return ''; } $post_id = ! empty( $block->context['postId'] ) ? absint( $block->context['postId'] ) : get_the_ID(); $product = wc_get_product( $post_id ); if ( ! $product ) { return ''; } $html = threedvieweronline_iframe( get_post_meta( $product->get_id(), 'threed_model_url', true ), array( 'width' => get_post_meta( $product->get_id(), 'threed_piframe_width', true ), 'height' => get_post_meta( $product->get_id(), 'threed_piframe_height', true ), ) ); return '' !== $html ? '
' . $html . '
' : ''; } /** * Register the tinymce button * * @since 1.0.0 */ public function threed_add_my_custom_tinymce_button() { global $typenow; if ( ! in_array( $typenow, array( 'product' ), true ) ) { return; } if ( 'true' === get_user_option( 'rich_editing' ) ) { add_filter( 'mce_external_plugins', array( $this, 'threed_mce_external_plugins_callack' ) ); add_filter( 'mce_buttons', array( $this, 'threed_mce_buttons_callack' ) ); } } /** * Add Tinymce plugin file. * * @param array $plugin_array Contains tiymce plugin files paths. * @since 1.0.0 */ public function threed_mce_external_plugins_callack( $plugin_array ) { $plugin_array['threed_mce_button1'] = plugins_url( '/admin/js/threed-mce-button1.js', THREED_PLUGIN_FILE ); return $plugin_array; } /** * Add Tinymce button. * * @param array $buttons Contains tiymce buttons. * @since 1.0.0 */ public function threed_mce_buttons_callack( $buttons ) { array_push( $buttons, 'threed_mce_button1' ); return $buttons; } /** * Register the product meta boxes * * @param array $post_type contains postype slug. * @since 1.0.0 */ public function threed_product_register_meta_boxes( $post_type ) { if ( 'product' === $post_type ) { add_meta_box( 'threed-viewer-online', __( '3D Viewer Online', '3dvieweronline-wp' ), array( $this, 'threed_product_meta_box_callback' ), 'product' ); } } /** * Meta Box callback prints the html * * @param WP_Post $post contains cuurent post object. * @since 1.0.0 */ public function threed_product_meta_box_callback( $post ) { if ( 'product' === $post->post_type ) { // Add an nonce field so we can check for it later. wp_nonce_field( 'threed_viewer_online', 'threed_viewer_online_nonce' ); // Use get_post_meta to retrieve an existing value from the database. $value = get_post_meta( $post->ID, 'threed_model_url', true ); $piwidth = get_post_meta( $post->ID, 'threed_piframe_width', true ); $piheight = get_post_meta( $post->ID, 'threed_piframe_height', true ); // Display the form, using the current value. ?>
settings['threed_iframe_width'] ) && '' !== $this->settings['threed_iframe_width'] ) { $piwidth = $this->settings['threed_iframe_width']; } else { $piwidth = '100%'; } } if ( '' === $piheight ) { if ( isset( $this->settings['threed_iframe_height'] ) && '' !== $this->settings['threed_iframe_height'] ) { $piheight = $this->settings['threed_iframe_height']; } else { $piheight = '500px'; } } $pos = strpos( $piwidth, '%' ); if ( false === $pos ) { $pos1 = strpos( $piwidth, 'px' ); if ( false === $pos1 ) { $piwidth = $piwidth . 'px'; } } $pos = strpos( $piheight, '%' ); if ( false === $pos ) { $pos1 = strpos( $piheight, 'px' ); if ( false === $pos1 ) { $piheight = $piheight . 'px'; } } if ( '' !== $value ) { echo wp_kses( threedvieweronline_iframe( $value, array( 'width' => $piwidth, 'height' => $piheight, 'lazy' => false ) ), array( 'iframe' => array( 'class' => true, 'id' => true, 'src' => true, 'title' => true, 'style' => true, 'loading' => true, 'allowfullscreen' => true ) ) ); } ?>
'' . esc_html__( 'Settings', '3dvieweronline-wp' ) . '', ); return array_merge( $action_links, $links ); } /** * Show row meta on the plugin screen. * * @param mixed $links Plugin Row Meta. * @param mixed $file Plugin Base file. * * @return array */ public static function plugin_row_meta( $links, $file ) { if ( THREED_PLUGIN_BASENAME === $file ) { $row_meta = array( 'youraccount' => '' . esc_html__( 'Your account', '3dvieweronline-wp' ) . '', 'howtousetheplugin' => '' . esc_html__( 'Get help', '3dvieweronline-wp' ) . '', 'contactus' => '' . esc_html__( 'Contact us', '3dvieweronline-wp' ) . '', ); return array_merge( $links, $row_meta ); } return (array) $links; } /** * Register the plugin settings link. * * @since 1.0.0 */ public function admin_menu() { $settings_page = add_menu_page( '3D Viewer Online WordPress Plugin', '3D Viewer Online', 'manage_options', 'threed-setting', array( $this, 'output' ), plugins_url( 'assets/images/icon.png', THREED_PLUGIN_FILE ), '80' ); add_action( 'load-' . $settings_page, array( $this, 'settings_page_init' ) ); } /** * Retrieve all display on page options. * * @since 1.0.0 */ public function getDisplayIframeOptions() { return array( 'after-product-title' => 'After product title', 'after-product-short-description' => 'After product short description', 'after-add-to-cart-button' => 'After add to cart button', ); } /** * Retrieve the settings of the plugin. * * @since 1.0.0 * @return array The settings of the plugin. */ public function get_settings() { $settings = get_option( 'settings-threed-iframe', array() ); return $this->settings = is_array( $settings ) ? $settings : array(); } /** * Retrieve the setting value. * * @since 1.0.0 * @return array The settings of the plugin. */ public function getSettingValue( $setting ) { if ( isset( $this->settings[ $setting ] ) ) { return $this->settings[ $setting ]; } return ''; } /** * Add a update message for settings. * * @since 1.0.0 * @access public * @var string $message update Message. */ public function add_message( $message ) { $this->messages[] = $message; } /** * Add a error message for settings. * * @since 1.0.0 * @access public * @var string $error error Message. */ public function add_error( $error ) { $this->errors[] = $error; } /** * Retrieve the messages + errors of the plugin. * * @since 1.0.0 */ public function show_messages() { $returndata = ''; if ( count( $this->errors ) > 0 ) { foreach ( $this->errors as $error ) { $returndata .= '

' . esc_html( $error ) . '

'; } } elseif ( count( $this->messages ) > 0 ) { foreach ( $this->messages as $message ) { $returndata .= '

' . esc_html( $message ) . '

'; } } return $returndata; } /** * Init method for setting page. * * @since 1.0.0 */ public function settings_page_init() { // Save settings if data has been posted. if ( ! empty( $_POST['threed-save'] ) ) { // Check if nonce is set. if ( ! current_user_can( 'manage_options' ) || ! isset( $_POST['_wpnonce'] ) || ! is_string( $_POST['_wpnonce'] ) ) { return false; } // Verify the nonce. if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['_wpnonce'] ) ), 'threed_viewer_settings' ) ) { return false; } $this->save(); } } /** * Retrieve Settings form. * Handles the display of the main settings page in admin. * * @since 1.0.0 */ public function output() { $this->show_setup_guide(); require_once THREED_PLUGIN_DIR . '/admin/partials/threedvieweronline-iframe-admin-display.php'; } /** * Save the settings. * Handles the save & update settings in database. * * @since 1.0.0 */ public function save() { // Check if nonce is set. if ( ! current_user_can( 'manage_options' ) || ! isset( $_POST['_wpnonce'] ) || ! is_string( $_POST['_wpnonce'] ) ) { return false; } // Verify the nonce. if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['_wpnonce'] ) ), 'threed_viewer_settings' ) ) { return false; } foreach ( array( 'threed_enable_product_tab', 'threed_enable_product_icon', 'threed_tab_title', 'threed_icon_display', 'threed_icon' ) as $field ) { if ( isset( $_POST[ $field ] ) && ! is_string( $_POST[ $field ] ) ) { return false; } } if ( ! $this->validation( $_POST ) ) { return false; } $settings = $this->get_settings(); $settings['threed_enable_product_tab'] = isset( $_POST['threed_enable_product_tab'] ) && 'on' === $_POST['threed_enable_product_tab'] ? 'on' : 'off'; $settings['threed_enable_product_icon'] = isset( $_POST['threed_enable_product_icon'] ) && 'on' === $_POST['threed_enable_product_icon'] ? 'on' : 'off'; $settings['threed_tab_title'] = isset( $_POST['threed_tab_title'] ) ? sanitize_text_field( wp_unslash( $_POST['threed_tab_title'] ) ) : ''; $threed_icon_display = isset( $_POST['threed_icon_display'] ) ? sanitize_key( wp_unslash( $_POST['threed_icon_display'] ) ) : ''; $settings['threed_icon_display'] = array_key_exists( $threed_icon_display, $this->getDisplayIframeOptions() ) ? $threed_icon_display : 'after-product-title'; $settings['threed_icon'] = isset( $_POST['threed_icon'] ) ? esc_url_raw( wp_unslash( $_POST['threed_icon'] ), array( 'http', 'https' ) ) : ''; $settings['threed_iframe_width'] = threedvieweronline_dimension( isset( $settings['threed_iframe_width'] ) ? $settings['threed_iframe_width'] : '', '100%' ); $settings['threed_iframe_height'] = threedvieweronline_dimension( isset( $settings['threed_iframe_height'] ) ? $settings['threed_iframe_height'] : '', '500px' ); update_option( 'settings-threed-iframe', $settings, true ); $this->settings = get_option( 'settings-threed-iframe' ); $this->add_message( esc_html__( 'Your settings have been saved.', '3dvieweronline-wp' ) ); } /** * Validate request data. * Handles the request data. * * @since 1.0.0 */ public function validation( $data ) { $supported_image = array( 'jpg', 'jpeg', 'png' ); $error = 0; if ( isset( $data['threed_enable_product_tab'] ) && 'on' === $data['threed_enable_product_tab'] ) { if ( isset( $data['threed_tab_title'] ) && empty( $data['threed_tab_title'] ) ) { $this->add_error( esc_html__( 'Product Tab Title is required.', '3dvieweronline-wp' ) ); $error = 1; } } if ( isset( $data['threed_icon'] ) && ! empty( $data['threed_icon'] ) ) { $icon_url = threedvieweronline_url( wp_unslash( $data['threed_icon'] ) ); $path = wp_parse_url( $icon_url, PHP_URL_PATH ); $image_ext = is_string( $path ) ? strtolower( pathinfo( $path, PATHINFO_EXTENSION ) ) : ''; $image_ext = str_replace( '.', '', $image_ext ); if ( ! in_array( $image_ext, $supported_image ,true ) ) { $this->add_error( esc_html__( '3D Icon must be a file of type: jpeg, png, jpg.', '3dvieweronline-wp' ) ); $error = 1; } } if ( $error ) { return false; } return true; } }