'Currency settings saved successfully', 'symbol' => $symbol, 'position' => $position )); } add_action('wp_ajax_ppc3d_save_currency_settings', 'ppc3d_save_currency_settings'); function ppc3d_stl_parser_admin_menu() { // Add main menu page add_menu_page( '3D Calculator', // Page title '3D Calculator', // Menu title 'manage_options', // Capability 'stl_parser_settings', // Menu slug 'ppc3d_stl_parser_settings_page', // Callback function plugins_url('../images/fav-icon-dashboard.png', ppc3d_file) // Use the constant for the image path ); // Add submenu pages add_submenu_page( 'stl_parser_settings', // Parent slug 'Settings', // Page title 'Settings', // Menu title 'manage_options', // Capability 'stl_parser_settings', // Menu slug (same as parent to keep this as the default page) 'ppc3d_stl_parser_settings_page' // Callback function ); // Add Email Settings page add_submenu_page( 'stl_parser_settings', // Parent slug 'Email Settings', // Page title 'Email Settings', // Menu title 'manage_options', // Capability 'stl_parser_email_settings', // Menu slug 'ppc3d_stl_parser_email_settings_page' // Callback function ); // Add Usage Guide page add_submenu_page( 'stl_parser_settings', // Parent slug 'Usage Guide', // Page title 'Usage Guide', // Menu title 'manage_options', // Capability 'stl_parser_usage_guide', // Menu slug 'ppc3d_stl_parser_usage_guide_page' // Callback function ); // Add Support page add_submenu_page( 'stl_parser_settings', // Parent slug 'Support', // Page title 'Support', // Menu title 'manage_options', // Capability 'stl_parser_support', // Menu slug 'ppc3d_stl_parser_support_page' // Callback function ); // Add File Manager page add_submenu_page( 'stl_parser_settings', // Parent slug 'File Manager', // Page title 'File Manager', // Menu title 'manage_options', // Capability 'stl_parser_file_manager', // Menu slug 'ppc3d_render_file_manager_page' // Callback function ); // Add Email Template page add_submenu_page( 'stl_parser_settings', // Parent slug 'Email Template', // Page title 'Email Template', // Menu title 'manage_options', // Capability 'stl_parser_email_templates', // Menu slug 'ppc3d_stl_parser_email_templates_page' // Callback function ); } add_action('admin_menu', 'ppc3d_stl_parser_admin_menu'); // Ensure dashicons are loaded in admin and add tooltip functionality function ppc3d_admin_enqueue_scripts() { wp_enqueue_style('dashicons'); // Enqueue jQuery UI for tooltips wp_enqueue_script('jquery'); wp_enqueue_script('jquery-ui-core'); wp_enqueue_script('jquery-ui-tooltip'); // Add custom CSS for tooltips, menu icon alignment, save buttons and toast notifications wp_add_inline_style('dashicons', ' .ppc3d-tooltip { display: inline-block; color: #0073aa; cursor: help; margin-left: 5px; vertical-align: middle; } .ui-tooltip { padding: 8px 12px; background-color: #333; color: #fff; border-radius: 6px; font-size: 13px; max-width: 300px; box-shadow: 0 0 5px rgba(0,0,0,0.3); z-index: 9999; border: none; } /* Menu icon and title alignment */ #adminmenu li.menu-top.toplevel_page_stl_parser_settings .wp-menu-image { display: inline-block; vertical-align: middle; float: none; width: auto; margin-top: -7px; margin-left: 8px; } #adminmenu li.menu-top.toplevel_page_stl_parser_settings .wp-menu-name { display: inline-block; vertical-align: middle; padding-left: 5px; } #adminmenu li.menu-top.toplevel_page_stl_parser_settings a.menu-top { display: flex; align-items: center; height: auto; } /* Input with save button styling */ .ppc3d-input-with-save { display: flex; gap: 10px; align-items: center; position: relative; } .ppc3d-input-with-save input { flex: 1; padding-right: 70px; } .ppc3d-save-button { position: absolute; right: 0; top: 0; bottom: 0; background-color: #0D95B3; color: white; border: none; padding: 8px 15px; border-radius: 4px; cursor: pointer; transition: all 0.3s; opacity: 0; visibility: hidden; transform: translateX(10px); } .ppc3d-input-with-save.active .ppc3d-save-button { opacity: 1; visibility: visible; transform: translateX(0); } .ppc3d-save-button:hover { background-color: #0a7a94; } /* Toast notification styling */ .ppc3d-toast { position: fixed; top: 50px; right: 20px; background-color: #4CAF50; color: white; padding: 15px 20px; border-radius: 4px; box-shadow: 0 2px 5px rgba(0,0,0,0.2); z-index: 9999; opacity: 0; transition: opacity 0.3s; display: flex; align-items: center; } .ppc3d-toast.show { opacity: 1; } .ppc3d-toast.error { background-color: #f44336; } .ppc3d-toast .dashicons { margin-right: 10px; } '); // Register and enqueue a custom JavaScript file for save buttons and toast notifications wp_register_script('ppc3d-admin-script', plugins_url('../js/admin-script.js', ppc3d_file), array('jquery', 'jquery-ui-tooltip'), '1.0.0', true); wp_enqueue_script('ppc3d-admin-script'); // Add nonce for AJAX calls wp_localize_script('ppc3d-admin-script', 'ppc3d_ajax', array( 'ajax_url' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('ppc3d_upload_stl_nonce') )); // Initialize tooltips and add tooltip icons wp_add_inline_script('jquery-ui-tooltip', ' jQuery(document).ready(function($) { // Initialize tooltips $(".ppc3d-tooltip").tooltip({ items: "[data-tooltip]", content: function() { return $(this).data("tooltip"); }, position: { my: "left+15 center", at: "right center" }, show: { effect: "fadeIn", duration: 200 }, hide: { effect: "fadeOut", duration: 200 } }); // Add tooltip icons to all option fields var tooltipData = { "enable_technology_options_field": "Configure different 3D printing technologies available to users (FDM, SLA, SLS, etc).", "enable_material_options_field": "Configure different materials available for 3D printing (PLA, ABS, PETG, Resin, etc).", "enable_quality_options_field": "Configure different print quality settings (layer height, resolution) available to users.", "enable_infill_options_field": "Configure different infill percentages and patterns available for 3D prints.", "enable_color_options_field": "Configure different color choices available for 3D printing." }; // For each field, find the label and add the tooltip icon $.each(tooltipData, function(fieldId, tooltipText) { var label = $("#" + fieldId).closest("tr").find("label"); if (label.length) { label.append(" "); } }); }); '); } add_action('admin_enqueue_scripts', 'ppc3d_admin_enqueue_scripts'); // Callback function to display settings page function ppc3d_stl_parser_settings_page() { ?>

3D Print Calculator Settings

To add the plugin to your site add this shortcode to any page [ppc3d_stl_upload_form]. if you need more guidance refer to Usage Guide page.

'boolean', 'sanitize_callback' => 'rest_sanitize_boolean', 'default' => false, ]); add_settings_section('stl_parser_settings_section', '', 'ppc3d_stl_parser_settings_section_callback', 'stl_parser_settings'); // Add field for cost_per_cc add_settings_field('ppc3d_stl_parser_settings_wrapper', '', 'ppc3d_stl_parser_settings_wrapper_callback', 'stl_parser_settings', 'stl_parser_settings_section'); add_settings_field( 'ppc3d_enable_bulk_orders', 'Enable bulk orders', 'ppc3d_enable_bulk_orders_callback', 'stl_parser_settings', 'enable_bulk_orders_setting' ); // Register setting to enable/disable file upload section register_setting('ppc3d_stl_parser_settings_group', 'ppc3d_show_file_upload_section', 'intval'); // Add section for file upload settings add_settings_section('enable_bulk_orders_setting', 'Enable Bulk Order ', null, 'stl_parser_settings'); add_settings_section('file_upload_settings_section', 'File Upload Preference ', 'ppc3d_file_upload_settings_section_callback', 'stl_parser_settings'); // Add fields for customizing options if file upload section is enabled add_settings_field('enable_technology_options_field', 'Printing Technology Options', 'ppc3d_enable_technology_options_field_callback', 'stl_parser_settings', 'file_upload_settings_section'); add_settings_field('printing_technology_options_field', '', 'ppc3d_printing_technology_options_field_callback', 'stl_parser_settings', 'file_upload_settings_section'); add_settings_field('enable_material_options_field', 'Material Options', 'ppc3d_enable_material_options_field_callback', 'stl_parser_settings', 'file_upload_settings_section'); add_settings_field('material_options_field', '', 'ppc3d_material_options_field_callback', 'stl_parser_settings', 'file_upload_settings_section'); add_settings_field('enable_quality_options_field', 'Quality Options', 'ppc3d_enable_quality_options_field_callback', 'stl_parser_settings', 'file_upload_settings_section'); add_settings_field('quality_options_field', '', 'ppc3d_quality_options_field_callback', 'stl_parser_settings', 'file_upload_settings_section'); add_settings_field('enable_infill_options_field', 'Infill Options', 'ppc3d_enable_infill_options_field_callback', 'stl_parser_settings', 'file_upload_settings_section'); add_settings_field('infill_options_field', '', 'ppc3d_infill_options_field_callback', 'stl_parser_settings', 'file_upload_settings_section'); add_settings_field('enable_color_options_field', 'Color Options', 'ppc3d_enable_color_options_field_callback', 'stl_parser_settings', 'file_upload_settings_section'); add_settings_field('color_options_field', '', 'ppc3d_color_options_field_callback', 'stl_parser_settings', 'file_upload_settings_section'); } add_action('admin_init', 'ppc3d_stl_parser_register_settings'); // Field callback function for currency setting function ppc3d_stl_parser_currency_field_callback() { $currency = get_option('ppc3d_currency_symbol', '$'); $position = get_option('ppc3d_currency_position', 'before'); echo '

Currency Settings

Set the currency symbol and position for displaying prices.

'; // End card } // Section callback function function ppc3d_stl_parser_settings_section_callback() { echo ''; } // Field callback function function ppc3d_stl_parser_cost_per_cc_field_callback() { $value = get_option('ppc3d_stl_parser_cost_per_cc'); $currency = get_option('ppc3d_currency_symbol', '$'); $position = get_option('ppc3d_currency_position', 'before'); echo '

Cost per Cubic Centimeter

Enter the base cost per cubic centimeter for 3D printing calculations (in ' . esc_html($currency) . ').

' . ($position === 'before' ? '' . esc_html($currency) . '' : '') . ' ' . ($position === 'after' ? '' . esc_html($currency) . '' : '') . '
'; } // Wrapper function to display all settings cards in a container function ppc3d_stl_parser_settings_wrapper_callback() { echo '
'; ppc3d_stl_parser_cost_per_cc_field_callback(); ppc3d_stl_parser_currency_field_callback(); echo '
'; } // Section callback function for file upload settings function ppc3d_file_upload_settings_section_callback() { // Add the info icon with tooltip after the section title echo ''; echo '

Configure options for the file upload section.

'; } // Field callback function for printing technology options function ppc3d_show_printing_technology_options_field_callback() { $enabled = get_option('ppc3d_enable_technology_options', 0); if ($enabled) { $saved_options = get_option('ppc3d_printing_technology_options', array()); ?>

$option, 'value' => $value, 'description' => $description ); update_option('ppc3d_printing_technology_options', $saved_options); wp_send_json_success('Printing technology option added successfully.'); } else { wp_send_json_error('Invalid request.'); } wp_die(); // This is required to terminate immediately and return a proper response } add_action('wp_ajax_add_printing_technology_option', 'ppc3d_add_printing_technology_option_callback'); //Callback Function for Printing Technnology Option function ppc3d_edit_printing_technology_option_callback() { // Verify nonce if (!isset($_POST['nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'ppc3d_upload_stl_nonce')) { wp_send_json_error('Nonce verification failed.'); wp_die(); } // Validate required fields $required_fields = ['option_id', 'original_name', 'printing_technology', 'printing_technology_value', 'printing_technology_description']; foreach ($required_fields as $field) { if (!isset($_POST[$field])) { wp_send_json_error("Missing required field: $field"); wp_die(); } } $old_option_id = sanitize_text_field(wp_unslash($_POST['option_id'])); $original_name = sanitize_text_field(wp_unslash($_POST['original_name'])); $new_option = sanitize_text_field(wp_unslash($_POST['printing_technology'])); $new_value = floatval($_POST['printing_technology_value']); $new_description = sanitize_text_field(wp_unslash($_POST['printing_technology_description'])); // Get existing options $saved_options = get_option('ppc3d_printing_technology_options', array()); // Check if original option exists if (!isset($saved_options[$original_name])) { wp_send_json_error('Original option not found.'); wp_die(); } // Handle name change if ($original_name !== $new_option) { // Check if new name already exists (except for the current option) if (isset($saved_options[$new_option])) { wp_send_json_error('An option with this name already exists.'); wp_die(); } // Create new entry with new name $saved_options[$new_option] = [ 'name' => $new_option, 'value' => $new_value, 'description' => $new_description ]; // Remove old entry unset($saved_options[$original_name]); } else { // Just update the existing entry $saved_options[$original_name] = [ 'name' => $new_option, 'value' => $new_value, 'description' => $new_description ]; } // Save updated options if (update_option('ppc3d_printing_technology_options', $saved_options)) { wp_send_json_success([ 'message' => 'Option updated successfully', 'new_name' => $new_option, 'new_value' => $new_value, 'new_description' => $new_description ]); } else { wp_send_json_error('Failed to update option.'); } wp_die(); } add_action('wp_ajax_edit_printing_technology_option', 'ppc3d_edit_printing_technology_option_callback'); // Callback function to delete printing technology option function ppc3d_delete_printing_technology_option_callback() { // Verify nonce if (! isset($_POST['nonce']) || ! wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'ppc3d_upload_stl_nonce')) { // Nonce verification failed wp_die('Nonce verification failed. Please refresh the page and try again.'); } if (isset($_POST['optionName'])) { $optionName = sanitize_text_field(wp_unslash($_POST['optionName'])); // Get current printing technology options $printingTechnologyOptions = get_option('ppc3d_printing_technology_options', array()); // Check if the option exists if (isset($printingTechnologyOptions[$optionName])) { // Remove the option unset($printingTechnologyOptions[$optionName]); update_option('ppc3d_printing_technology_options', $printingTechnologyOptions); // Return success response wp_send_json_success(); } else { // Return error response if the option does not exist wp_send_json_error('Printing technology option does not exist.'); } } else { // Return error response if option name is not provided wp_send_json_error('Option name not provided.'); } } add_action('wp_ajax_delete_printing_technology_option', 'ppc3d_delete_printing_technology_option_callback'); // Field callback function for material options function ppc3d_show_material_options_field_callback() { $enabled = get_option('ppc3d_enable_material_options', 0); if ($enabled) { $saved_options = get_option('ppc3d_material_options', array()); ?>

$option, 'value' => $value, 'description' => $description ); update_option('ppc3d_material_options', $saved_options); wp_send_json_success('Material option added successfully.'); } else { wp_send_json_error('Invalid request.'); } wp_die(); // This is required to terminate immediately and return a proper response } add_action('wp_ajax_add_material_option', 'ppc3d_add_material_option_callback'); function ppc3d_edit_material_option_callback() { // Verify nonce if (!isset($_POST['nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'ppc3d_upload_stl_nonce')) { wp_send_json_error('Nonce verification failed.'); wp_die(); } // Validate required fields $required_fields = ['option_id', 'original_name', 'material', 'material_value', 'material_description']; foreach ($required_fields as $field) { if (!isset($_POST[$field])) { wp_send_json_error("Missing required field: $field"); wp_die(); } } // Sanitize and prepare input data $old_option_id = sanitize_text_field(wp_unslash($_POST['option_id'])); $original_name = sanitize_text_field(wp_unslash($_POST['original_name'])); $new_option = sanitize_text_field(wp_unslash($_POST['material'])); $new_value = floatval($_POST['material_value']); $new_description = sanitize_text_field(wp_unslash($_POST['material_description'])); // Get existing options $saved_options = get_option('ppc3d_material_options', array()); // Check if original option exists if (!isset($saved_options[$original_name])) { wp_send_json_error('Original option not found.'); wp_die(); } // Handle name change if ($original_name !== $new_option) { // Check if new name already exists (except for the current option) if (isset($saved_options[$new_option])) { wp_send_json_error('An option with this name already exists.'); wp_die(); } // Create new entry with new name $saved_options[$new_option] = [ 'name' => $new_option, 'value' => $new_value, 'description' => $new_description ]; // Remove old entry unset($saved_options[$original_name]); } else { // Just update the existing entry $saved_options[$original_name] = [ 'name' => $new_option, 'value' => $new_value, 'description' => $new_description ]; } // Save updated options if (update_option('ppc3d_material_options', $saved_options)) { wp_send_json_success([ 'message' => 'Material option updated successfully', 'new_name' => $new_option, 'new_value' => $new_value, 'new_description' => $new_description ]); } else { wp_send_json_error('Failed to update material option.'); } wp_die(); } add_action('wp_ajax_edit_material_option', 'ppc3d_edit_material_option_callback'); // Callback function to delete material option function ppc3d_delete_material_option_callback() { // Verify nonce if (! isset($_POST['nonce']) || ! wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'ppc3d_upload_stl_nonce')) { // Nonce verification failed wp_die('Nonce verification failed. Please refresh the page and try again.'); } if (isset($_POST['optionName'])) { $optionName = sanitize_text_field(wp_unslash($_POST['optionName'])); // Get current material options $materialOptions = get_option('ppc3d_material_options', array()); // Check if the option exists if (isset($materialOptions[$optionName])) { // Remove the option unset($materialOptions[$optionName]); update_option('ppc3d_material_options', $materialOptions); // Return success response wp_send_json_success(); } else { // Return error response if the option does not exist wp_send_json_error('Material option does not exist.'); } } else { // Return error response if option name is not provided wp_send_json_error('Option name not provided.'); } } add_action('wp_ajax_delete_material_option', 'ppc3d_delete_material_option_callback'); // Field callback function for quality options function ppc3d_show_quality_options_field_callback() { $enabled = get_option('ppc3d_enable_quality_options', 0); if ($enabled) { $saved_options = get_option('ppc3d_quality_options', array()); ?>
$value) : ?>
$option, 'value' => $value, 'description' => $description ); update_option('ppc3d_quality_options', $saved_options); wp_send_json_success('Quality option added successfully.'); wp_die(); } add_action('wp_ajax_add_quality_option', 'ppc3d_add_quality_option_callback'); function ppc3d_edit_quality_option_callback() { // Verify nonce if (!isset($_POST['nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'ppc3d_upload_stl_nonce')) { wp_send_json_error('Nonce verification failed.'); wp_die(); } // Validate required fields $required_fields = ['option_id', 'original_name', 'quality', 'quality_value', 'quality_description']; foreach ($required_fields as $field) { if (!isset($_POST[$field])) { wp_send_json_error("Missing required field: $field"); wp_die(); } } $old_option_id = sanitize_text_field(wp_unslash($_POST['option_id'])); $original_name = sanitize_text_field(wp_unslash($_POST['original_name'])); $new_option = sanitize_text_field(wp_unslash($_POST['quality'])); $new_value = floatval($_POST['quality_value']); $new_description = sanitize_text_field(wp_unslash($_POST['quality_description'])); // Get existing options $saved_options = get_option('ppc3d_quality_options', array()); // Check if original option exists if (!isset($saved_options[$original_name])) { wp_send_json_error('Original option not found.'); wp_die(); } // Handle name change if ($original_name !== $new_option) { // Check if new name already exists (except for the current option) if (isset($saved_options[$new_option])) { wp_send_json_error('An option with this name already exists.'); wp_die(); } // Create new entry with new name $saved_options[$new_option] = [ 'name' => $new_option, 'value' => $new_value, 'description' => $new_description ]; // Remove old entry unset($saved_options[$original_name]); } else { // Just update the existing entry $saved_options[$original_name] = [ 'name' => $new_option, 'value' => $new_value, 'description' => $new_description ]; } // Save updated options if (update_option('ppc3d_quality_options', $saved_options)) { wp_send_json_success([ 'message' => 'Option updated successfully', 'new_name' => $new_option, 'new_value' => $new_value, 'new_description' => $new_description ]); } else { wp_send_json_error('Failed to update option.'); } wp_die(); } add_action('wp_ajax_edit_quality_option', 'ppc3d_edit_quality_option_callback'); // Callback function to delete quality option function ppc3d_delete_quality_option_callback() { // Verify nonce if (! isset($_POST['nonce']) || ! wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'ppc3d_upload_stl_nonce')) { // Nonce verification failed wp_die('Nonce verification failed. Please refresh the page and try again.'); } if (isset($_POST['optionName'])) { $optionName = sanitize_text_field(wp_unslash($_POST['optionName'])); // Get current quality options $qualityOptions = get_option('ppc3d_quality_options', array()); // Check if the option exists if (isset($qualityOptions[$optionName])) { // Remove the option unset($qualityOptions[$optionName]); update_option('ppc3d_quality_options', $qualityOptions); // Return success response wp_send_json_success(); } else { // Return error response if the option does not exist wp_send_json_error('Quality option does not exist.'); } } else { // Return error response if option name is not provided wp_send_json_error('Option name not provided.'); } } add_action('wp_ajax_delete_quality_option', 'ppc3d_delete_quality_option_callback'); // Field callback function for infill options function ppc3d_show_infill_options_field_callback() { $enabled = get_option('ppc3d_enable_infill_options', 0); if ($enabled) { $saved_options = get_option('ppc3d_infill_options', array()); ?>

$option, 'value' => $value, 'description' => $description ); update_option('ppc3d_infill_options', $saved_options); // Return success response wp_send_json_success('Infill option added successfully.'); wp_die(); } add_action('wp_ajax_add_infill_option', 'ppc3d_add_infill_option_callback'); //edit infill function ppc3d_edit_infill_option_callback() { // Verify nonce if (!isset($_POST['nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'ppc3d_upload_stl_nonce')) { wp_send_json_error('Nonce verification failed.'); wp_die(); } // Validate required fields $required_fields = ['infill_id', 'original_name', 'infill', 'infill_value', 'infill_description']; foreach ($required_fields as $field) { if (!isset($_POST[$field])) { wp_send_json_error("Missing required field: $field"); wp_die(); } } $old_infill_id = sanitize_text_field(wp_unslash($_POST['infill_id'])); $original_name = sanitize_text_field(wp_unslash($_POST['original_name'])); $new_infill = sanitize_text_field(wp_unslash($_POST['infill'])); $new_value = floatval($_POST['infill_value']); $new_description = sanitize_text_field(wp_unslash($_POST['infill_description'])); // Retrieve and update options $saved_options = get_option('ppc3d_infill_options', array()); if (!isset($saved_options[$original_name])) { wp_send_json_error('Original option not found.'); wp_die(); } if ($original_name !== $new_infill) { if (isset($saved_options[$new_infill])) { wp_send_json_error('An option with this name already exists.'); wp_die(); } $saved_options[$new_infill] = [ 'value' => $new_value, 'description' => $new_description ]; unset($saved_options[$original_name]); } else { $saved_options[$original_name] = [ 'value' => $new_value, 'description' => $new_description ]; } if (update_option('ppc3d_infill_options', $saved_options)) { wp_send_json_success('Option updated successfully.'); } else { wp_send_json_error('Failed to update option.'); } wp_die(); } add_action('wp_ajax_edit_infill_option', 'ppc3d_edit_infill_option_callback'); // Callback function to delete infill option function ppc3d_delete_infill_option_callback() { // Verify nonce if (! isset($_POST['nonce']) || ! wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'ppc3d_upload_stl_nonce')) { // Nonce verification failed wp_die('Nonce verification failed. Please refresh the page and try again.'); } if (isset($_POST['optionName'])) { $optionName = sanitize_text_field(wp_unslash($_POST['optionName'])); // Get current infill options $infillOptions = get_option('ppc3d_infill_options', array()); // Check if the option exists if (isset($infillOptions[$optionName])) { // Remove the option unset($infillOptions[$optionName]); update_option('ppc3d_infill_options', $infillOptions); // Return success response wp_send_json_success(); } else { // Return error response if the option does not exist wp_send_json_error('Infill option does not exist.'); } } else { // Return error response if option name is not provided wp_send_json_error('Option name not provided.'); } } add_action('wp_ajax_delete_infill_option', 'ppc3d_delete_infill_option_callback'); // Field callback function for color options function ppc3d_show_color_options_field_callback() { $enabled = get_option('ppc3d_enable_color_options', 0); if ($enabled) { $saved_options = get_option('ppc3d_color_options', array()); ?>
$value) : $checked = $first ? 'checked' : ''; // Check the first option $first = false; // Set flag to false after first option ?>
$option, 'value' => $value, // Color hex code 'price' => $price, // Price value 'description' => $description ); update_option('ppc3d_color_options', $saved_options); // Return success response wp_send_json_success('Color option added successfully.'); wp_die(); } add_action('wp_ajax_add_color_option', 'ppc3d_add_color_option_callback'); //Color ni siya function ppc3d_edit_color_option_callback() { // Verify nonce if (!isset($_POST['nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'ppc3d_upload_stl_nonce')) { wp_send_json_error('Nonce verification failed.'); wp_die(); } // Validate required fields $required_fields = ['color_id', 'original_name', 'color', 'color_value', 'color_price', 'color_description']; foreach ($required_fields as $field) { if (!isset($_POST[$field])) { wp_send_json_error("Missing required field: $field"); wp_die(); } } $colorId = sanitize_text_field(wp_unslash($_POST['color_id'])); $originalName = sanitize_text_field(wp_unslash($_POST['original_name'])); $newColor = sanitize_text_field(wp_unslash($_POST['color'])); $newValue = sanitize_text_field(wp_unslash($_POST['color_value'])); // Color hex code $newPrice = floatval($_POST['color_price']); // Price as float $newDescription = sanitize_text_field(wp_unslash($_POST['color_description'])); // Get existing options $saved_options = get_option('ppc3d_color_options', []); // Handle name change if ($originalName !== $newColor) { if (isset($saved_options[$newColor])) { wp_send_json_error('A color with this name already exists.'); wp_die(); } // Create new entry with new name $saved_options[$newColor] = [ 'value' => $newValue, 'price' => $newPrice, 'description' => $newDescription, ]; // Remove old entry unset($saved_options[$originalName]); } else { // Update existing entry $saved_options[$originalName] = [ 'value' => $newValue, 'price' => $newPrice, 'description' => $newDescription, ]; } // Save updated options if (update_option('ppc3d_color_options', $saved_options)) { wp_send_json_success([ 'message' => 'Color option updated successfully.', 'new_name' => $newColor, 'new_value' => $newValue, 'new_description' => $newDescription, ]); } else { wp_send_json_error('Failed to update color option.'); } wp_die(); } add_action('wp_ajax_edit_color_option', 'ppc3d_edit_color_option_callback'); // Callback function to delete color option function ppc3d_delete_color_option_callback() { // Verify nonce if (! isset($_POST['nonce']) || ! wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'ppc3d_upload_stl_nonce')) { // Nonce verification failed wp_die('Nonce verification failed. Please refresh the page and try again.'); } if (isset($_POST['optionName'])) { $optionName = sanitize_text_field(wp_unslash($_POST['optionName'])); // Get current color options $colorOptions = get_option('ppc3d_color_options', array()); // Check if the option exists if (isset($colorOptions[$optionName])) { // Remove the option unset($colorOptions[$optionName]); update_option('ppc3d_color_options', $colorOptions); // Return success response wp_send_json_success(); } else { // Return error response if the option does not exist wp_send_json_error('Color option does not exist.'); } } else { // Return error response if option name is not provided wp_send_json_error('Option name not provided.'); } } add_action('wp_ajax_delete_color_option', 'ppc3d_delete_color_option_callback'); /** * AJAX handler for saving individual settings */ function ppc3d_save_setting_callback() { // Check nonce for security if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'ppc3d_upload_stl_nonce')) { wp_send_json_error('Security check failed'); } // Get option name and value $option_name = isset($_POST['option_name']) ? sanitize_text_field($_POST['option_name']) : ''; $option_value = isset($_POST['option_value']) ? sanitize_text_field($_POST['option_value']) : ''; // Validate option name $valid_options = [ 'ppc3d_stl_parser_cost_per_cc' ]; if (!in_array($option_name, $valid_options)) { wp_send_json_error('Invalid option name'); } // Update option in database $result = update_option($option_name, $option_value); if ($result) { wp_send_json_success(['message' => 'Setting saved successfully']); } else { wp_send_json_error('Failed to update setting'); } } add_action('wp_ajax_ppc3d_save_setting', 'ppc3d_save_setting_callback'); // Add confirmation modal HTML at the end of the settings page function ppc3d_add_confirmation_modal() { ?>
×

Confirm Deletion

Are you sure you want to delete this item? This action cannot be undone.

Printing Technology Options

/>
|
$value_data) : ?>
Option Name Description Price Per CC Actions
No options added yet. Click 'Add Option' to create your first option.
$max_length) ? esc_html(mb_substr($full_desc, 0, $max_length)) . '...' : esc_html($full_desc); ?>
1) : ?>
1) : $prev_url = add_query_arg('tech_page', $current_page - 1); ?> « Previous Next »

Material Options

/>
|
$value_data) : ?>
Option Name Description Price Per CC Actions
No options added yet. Click 'Add Material Option' to create your first option.
$max_length) ? esc_html(mb_substr($full_desc, 0, $max_length)) . '...' : esc_html($full_desc); ?>

Quality Options

/>
|
$value_data) : ?>
Option Name Description Price Per CC Actions
No options added yet. Click 'Add Quality Option' to create your first option.
$max_length) { echo esc_html(mb_substr($full_desc, 0, $max_length)) . '...'; } else { echo esc_html($full_desc); } ?>
1) : ?>
1) : $prev_url = add_query_arg('quality_page', $current_page - 1); ?> « Previous Next »

Infill Options

/>
|
$value_data) : ?>
Option Name Description Price Per CC Actions
No options added yet. Click 'Add Infill Option' to create your first option.
$max_length) ? esc_html(mb_substr($full_desc, 0, $max_length)) . '...' : esc_html($full_desc); ?>
1) : $prev_url = add_query_arg('infill_page', $current_page - 1); ?> « Previous Next »

Color Options

/>
|
$value_data) : ?>
Option Name Description Color Price Per CC Actions
No options added yet. Click 'Add Color Option' to create your first option.
$max_length) ? esc_html(mb_substr($full_desc, 0, $max_length)) . '...' : esc_html($full_desc); ?>
Price not set'; } ?>
1) : $prev_url = add_query_arg('color_page', $current_page - 1); ?> « Previous Next »
×

Add Printing Technology Option

×

Edit Printing Technology Option

×

Edit Material Option

×

Edit Quality Option

×

Edit Infill Option

×

Edit Color Option

×

Add Color Option

×

Add Material Option

×

View Printing Technology Option

×

View Material Option

×

View Quality Option

×

View Infill Option

×

View Color Option

3D Calculator - Email Settings

Configure email addresses for notifications and invoices. These emails will be used when customers submit orders through the 3D Print Calculator.

'; } /** * Notification email field callback */ function ppc3d_notification_email_field_callback() { $notification_email = get_option('ppc3d_notification_email', ''); echo ''; echo '

Email address that will receive notifications when new 3D print orders are submitted.

'; } /** * Invoice email field callback */ function ppc3d_invoice_email_field_callback() { $invoice_email = get_option('ppc3d_invoice_email', ''); echo ''; echo '

Email address that will be used as the sender for invoice emails to customers.

'; } /** * Email subject prefix field callback */ function ppc3d_email_subject_prefix_field_callback() { $subject_prefix = get_option('ppc3d_email_subject_prefix', '[3D Print]'); echo ''; echo '

Prefix to add to the subject line of all emails sent by the plugin.

'; } /** * Callback function for the Usage Guide page */ function ppc3d_stl_parser_usage_guide_page() { ?>

3D Calculator - Usage Guide

How to Use the 3D Print Pricing Calculator

Welcome to the usage guide for the 3D Print Pricing Calculator plugin. This page provides instructions on how to use and configure the plugin.

Getting Started

  1. Configure your basic settings on the Settings page
  2. Set up your printing technologies, materials, and other options
  3. Use the shortcode [ppc3d_stl_upload_form] on any page to display the 3D file upload form

Shortcode Usage

Add the calculator to any page or post using: [ppc3d_stl_upload_form]

Configuration Tips

"; $email_message .= "

Name: " . esc_html($name) . "

"; $email_message .= "

Email: " . esc_html($email) . "

"; $email_message .= "

Subject: " . esc_html($subject) . "

"; $email_message .= "

Message:

"; $email_message .= "

" . nl2br(esc_html($message)) . "

"; $email_message .= "

This email was sent from the 3D Print Pricing Calculator plugin's support form.

"; $email_message .= ""; // Set up headers $headers = array( 'Content-Type: text/html; charset=UTF-8', 'From: ' . get_bloginfo('name') . ' <' . get_option('admin_email') . '>', 'Reply-To: ' . $name . ' <' . $email . '>' ); // Check if we're in a local development environment $is_local = in_array($_SERVER['SERVER_NAME'], array('localhost', '127.0.0.1')) || strpos($_SERVER['SERVER_NAME'], '.local') !== false; if ($is_local) { // For local development, store the email in a transient and show success $email_data = array( 'to' => $to, 'subject' => $email_subject, 'message' => $email_message, 'headers' => $headers, 'time' => current_time('mysql') ); // Store the last 5 emails $stored_emails = get_transient('ppc3d_debug_emails'); if (!is_array($stored_emails)) { $stored_emails = array(); } // Add this email to the beginning of the array array_unshift($stored_emails, $email_data); // Keep only the last 5 emails $stored_emails = array_slice($stored_emails, 0, 5); // Save the emails set_transient('ppc3d_debug_emails', $stored_emails, 60 * 60 * 24); // Store for 24 hours // Show success message for local development $form_submitted = true; $form_message = 'Your message has been captured for local development testing. In production, this would be sent to support@pikocode.com.'; } else { // In production, actually send the email $mail_sent = wp_mail($to, $email_subject, $email_message, $headers); if ($mail_sent) { $form_submitted = true; $form_message = 'Your message has been sent successfully. We will get back to you as soon as possible.'; } else { $form_error = true; $form_message = 'There was an error sending your message. Please try again or contact us directly at support@pikocode.com.'; // Log the error for debugging error_log('3D Print Pricing Calculator: Failed to send support email from ' . $email); } } } } ?>

3D Calculator - Support

Local Development - Debug Information

Since you're running in a local environment, emails are captured instead of being sent. Here's the most recent captured email:

To:

Subject:

Time:

Message:

Support Resources

If you need help with the 3D Print Pricing Calculator plugin, here are some resources to assist you:

Documentation

Visit our documentation for detailed guides and tutorials.

Frequently Asked Questions

  • How do I add the calculator to a page?
    Use the shortcode [ppc3d_stl_upload_form] on any page or post.
  • Can I customize the appearance?
    Yes, you can modify the CSS in the plugin's style.css file.
  • How do I add new materials?
    Go to the Settings page and use the Materials section to add new options.

Contact Support

For additional help, please contact our support team at support@pikocode.com.

Feedback Form

'Option updated successfully']); } else { wp_send_json_error('Failed to update option'); } } add_action('wp_ajax_update_toggle_option', 'ppc3d_update_toggle_option_callback'); /** * Callback function for the Email Template page */ function ppc3d_stl_parser_email_templates_page() { require_once plugin_dir_path(__FILE__) . 'admin-email-templates.php'; ppc3d_email_templates_page(); } // Enable bulk orders callback function function ppc3d_enable_bulk_orders_callback() { $value = get_option('ppc3d_enable_bulk_orders', false); ?>
/>