From 3f0737bdd84dc1e4f2fd4f32a3d6adc9bb46c63a Mon Sep 17 00:00:00 2001 From: "Soare Robert Daniel (Mac 2023)" Date: Wed, 28 Aug 2024 17:50:37 +0300 Subject: [PATCH 01/31] refactor: typescript support and custom popup --- classes/fields.class.php | 21 ++++-- css/ppom-admin.css | 84 +++++++++++++++++++++++ global.d.ts | 133 ++++++++++++++++++++++++++++++++++++ js/admin/ppom-admin.js | 40 ++++++----- js/admin/ppom-meta-table.js | 80 ++++++++++++---------- js/popup.js | 102 +++++++++++++++++++++++++++ 6 files changed, 397 insertions(+), 63 deletions(-) create mode 100644 global.d.ts create mode 100644 js/popup.js diff --git a/classes/fields.class.php b/classes/fields.class.php index 4d00a5b6..6de04b42 100644 --- a/classes/fields.class.php +++ b/classes/fields.class.php @@ -68,18 +68,17 @@ function load_script( $hook ) { wp_enqueue_script( 'ppom-inputmask', PPOM_URL . '/js/inputmask/jquery.inputmask.min.js', array( 'jquery' ), '5.0.6', true ); + // Popup + wp_enqueue_script( 'ppom-popup', PPOM_URL . '/js/popup.js', [], PPOM_VERSION, true ); + // PPOM Meta Table File - wp_enqueue_script( 'ppom-meta-table', PPOM_URL . '/js/admin/ppom-meta-table.js', array( 'jquery' ), PPOM_VERSION, true ); + wp_enqueue_script( 'ppom-meta-table', PPOM_URL . '/js/admin/ppom-meta-table.js', array( 'jquery', 'ppom-popup' ), PPOM_VERSION, true ); // Font-awesome File if ( ppom_load_fontawesome() ) { wp_enqueue_style( 'ppom-fontawsome', PPOM_URL . '/css/font-awesome/css/font-awesome.min.css' ); } - // Swal Files - wp_enqueue_style( 'ppom-swal', PPOM_URL . '/js/sweetalert/sweetalert2.min.css' ); - wp_enqueue_script( 'ppom-swal', PPOM_URL . '/js/sweetalert/sweetalert2.js', [], PPOM_VERSION, true ); - // Select2 Files wp_enqueue_style( 'ppom-select2', PPOM_URL . '/css/select2.css' ); wp_enqueue_script( 'ppom-select2', PPOM_URL . '/js/select2.js', array( 'jquery' ), PPOM_VERSION, true ); @@ -136,7 +135,7 @@ function load_script( $hook ) { 'ppom-field', PPOM_URL . '/js/admin/ppom-admin.js', array( - 'ppom-swal', + 'ppom-popup', 'ppom-select2', 'ppom-tabletojson', 'ppom-datatables', @@ -166,7 +165,15 @@ function load_script( $hook ) { 'importLabel'=>esc_html__( 'Import Field Groups ', 'woocommerce-product-addon' ), 'importLockedLabel'=>esc_html__( 'Import Field Groups (PRO)', 'woocommerce-product-addon' ), 'freemiumCFRContent' => \PPOM_Freemium::get_instance()->get_freemium_cfr_content(), - 'freemiumCFRTab' => \PPOM_Freemium::TAB_KEY_FREEMIUM_CFR + 'freemiumCFRTab' => \PPOM_Freemium::TAB_KEY_FREEMIUM_CFR, + 'popup' => [ + 'confirmTitle' => __( 'Are you sure?', 'woocommerce-product-addon' ), + 'confirmationBtn' => __( 'Confirm', 'woocommerce-product-addon' ), + 'cancelBtn' => __( 'Cancel', 'woocommerce-product-addon' ), + 'finishTitle' => __( 'Done', 'woocommerce-product-addon' ), + 'errorTitle' => __( 'Error', 'woocommerce-product-addon' ), + 'checkFieldTitle' => __( 'Please at least check one field!', 'woocommerce-product-addon' ), + ] ] ); diff --git a/css/ppom-admin.css b/css/ppom-admin.css index ecef0789..4c37b6c5 100644 --- a/css/ppom-admin.css +++ b/css/ppom-admin.css @@ -1163,4 +1163,88 @@ a[data-modal-id="ppom-nm-plugins-modal"] { #ppom-admin-changelog-header-top { padding: 15px 30px 0 0; +} + +/* CSS for popup.js */ +.ppom-popup-overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.5); + display: flex; + justify-content: center; + align-items: center; + z-index: 1000; +} + +.ppom-popup { + background: #fff; + border-radius: 8px; + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); + width: 500px; + padding: 40px 50px 20px; + text-align: center; +} + +.ppom-popup-container { + display: flex; + flex-direction: column; + align-items: center; + + gap: 20px; +} + +.ppom-popup-title { + font-size: 2.5em; + margin: 0; + line-height: 1.3; + + color: #4caf50; +} + +.ppom-popup-text { + font-size: 1.4em; + line-height: 1.3; + margin: 0; +} + +.ppom-popup-actions { + display: flex; + justify-content: space-evenly; + width: 100%; +} + +.ppom-popup-actions button { + padding: 10px 20px; + border: none; + border-radius: 4px; + cursor: pointer; + font-size: 1.3em; + transition: background-color 0.3s ease; + min-width: 110px; + + color: #fff; + background-color: #4caf50; +} + +.ppom-popup-actions button:hover { + background-color: #4588a0; +} + +.ppom-popup-actions .ppom-btn-cancel { + background-color: #6c757d; +} + +.ppom-popup.ppom-error .ppom-popup-title { + color: #f44336; +} + +.ppom-popup.ppom-error .ppom-btn-confirm { + background-color: #f44336; +} + +.ppom-hide { + display: none; } \ No newline at end of file diff --git a/global.d.ts b/global.d.ts new file mode 100644 index 00000000..57e500a5 --- /dev/null +++ b/global.d.ts @@ -0,0 +1,133 @@ +interface PopupOptions { + title?: string; + text?: string; + hideCloseBtn?: boolean; + type?: 'error' | 'success'; + onConfirmation?: () => void; + onClose?: () => void; +} + +export declare class Popup { + overlay: HTMLDivElement; + popup: HTMLDivElement; + container: HTMLDivElement; + title: HTMLHeadingElement; + text: HTMLParagraphElement; + confirmButton: HTMLButtonElement; + cancelButton: HTMLButtonElement; + onConfirmation: () => void; + onClose: () => void; + + constructor(); + open(options?: PopupOptions): void; + close(): void; + confirm(): void; + show(): void; + hide(): void; +} + +interface GlobalVars { + i18n: { + addGroupUrl: string; + addGroupLabel: string; + bulkActionsLabel: string; + deleteLabel: string; + exportLabel: string; + exportLockedLabel: string; + importLabel: string; + importLockedLabel: string; + freemiumCFRContent: string; + freemiumCFRTab: string; + popup: { + confirmTitle: string; + confirmationBtn: string; + cancelBtn: string; + finishTitle: string; + errorTitle: string; + checkFieldTitle: string; + } + } +} + +interface BulkQuantityGlobal { + i18n: { + validation: { + end_bigger_than_start: string; + start_cannot_be_equal_with_end: string; + range_intersection: string; + invalid_pattern: string; + } + } +} + +interface FileUploadGlobal { + ajaxurl: string; + plugin_url: string; + file_upload_path_thumb: string; + file_upload_path: string; + mesage_max_files_limit: string; + file_inputs: any[]; + delete_file_msg: string; + plupload_runtime: string; + croppie_options: { + viewport: { + width: number; + height: number; + type: string; + }, + boundary: { + width: number; + height: number; + }, + enableExif: boolean; + enforceBoundary: boolean; + enableZoom: boolean; + showZoomer: boolean; + }[]; + ppom_file_upload_nonce: string; + ppom_file_delete_nonce: string; + enable_file_rename: boolean; + product_id: number; +} + +interface InputVarsGlobal { + ajaxurl: string; + ppom_inputs: any[]; + field_meta: any[]; + ppom_validate_nonce: string; + wc_thousand_sep: string; + wc_currency_pos: string; + wc_decimal_sep: string; + wc_no_decimal: number; + wc_product_price: number; + wc_product_regular_price: number; + total_discount_label: string; + price_matrix_heading: string; + product_base_label: string; + option_total_label: string; + fixed_fee_heading: string; + total_without_fixed_label: string; + product_quantity_label: string; + product_title: string; + per_unit_label: string; + show_price_per_unit: boolean; + text_quantity: string; + show_option_price: boolean; + is_shortcode: string; + plugin_url: string; + is_mobile: boolean; + product_id: number; + tax_prefix: string; +} + +/** + * Define global variables to allow IDE auto-completion and checking. + */ +declare global { + interface Window { + ppomPopup?: Popup; + ppom_vars: GlobalVars; + ppom_file_vars: FileUploadGlobal; + ppom_input_vars: InputVarsGlobal + } +} \ No newline at end of file diff --git a/js/admin/ppom-admin.js b/js/admin/ppom-admin.js index cf97597d..ce17f2c8 100644 --- a/js/admin/ppom-admin.js +++ b/js/admin/ppom-admin.js @@ -211,29 +211,27 @@ jQuery(function($) { var check_field = $('.ppom-check-one-field input[type="checkbox"]:checked'); if (check_field.length > 0) { - swal.fire({ - title: "Are you sure", - showCancelButton: true, - confirmButtonColor: "#DD6B55 ", - cancelButtonColor: "#DD6B55", - confirmButtonText: "Yes", - cancelButtonText: "No", - }).then( (result ) => { - if (!result.isConfirmed) return; - - $('.ppom_field_table').find('.ppom-check-one-field input').each(function(i, meta_field) { - - if (this.checked) { - var field_id = $(meta_field).val(); - // console.log(field_id) - $(meta_field).parent().parent().parent('.row_no_' + field_id + '').remove(); - } - $('.ppom_save_fields_model').find('#ppom_field_model_' + field_id + '').remove(); - }); - }); + window?.ppomPopup?.open({ + title: window?.ppom_vars?.i18n.popup.confirmTitle, + onConfirmation: () => { + $('.ppom_field_table').find('.ppom-check-one-field input').each(function(i, meta_field) { + + const field_id = $(meta_field).val(); + if (this.checked) { + // console.log(field_id) + $(meta_field).parent().parent().parent('.row_no_' + field_id + '').remove(); + } + $('.ppom_save_fields_model').find('#ppom_field_model_' + field_id + '').remove(); + }); + } + }) } else { - swal.fire("Please at least check one field!", "", "error"); + window?.ppomPopup?.open({ + title: window.ppom_vars.i18n.popup.checkFieldTitle, + type: "error", + hideCloseBtn: true + }) } }); diff --git a/js/admin/ppom-meta-table.js b/js/admin/ppom-meta-table.js index b75968e8..bc6fc44f 100644 --- a/js/admin/ppom-meta-table.js +++ b/js/admin/ppom-meta-table.js @@ -30,20 +30,12 @@ jQuery(function($){ 2- Delete Selected Products **/ function deleteSelectedProducts(checkedProducts_ids) { - swal.fire({ - title: "Are you sure?", - type: "warning", - showCancelButton: true, - confirmButtonColor: "#DD6B55 ", - cancelButtonColor: "#DD6B55", - confirmButtonText: "Yes", - cancelButtonText: "No", - }).then( (result ) => { - if (!result.isConfirmed) return; - + window?.ppomPopup?.open({ + title: window?.ppom_vars?.i18n.popup.confirmTitle, + onConfirmation: () => { $('#ppom_delete_selected_products_btn').html('Deleting...'); - var data = { + const data = { action : 'ppom_delete_selected_meta', productmeta_ids : checkedProducts_ids, ppom_meta_nonce : $("#ppom_meta_nonce").val() @@ -52,12 +44,22 @@ jQuery(function($){ $.post(ajaxurl, data, function(resp){ $('#ppom_delete_selected_products_btn').html('Delete'); if (resp) { - swal.fire({title: "Done", text: resp, type: "success" ,confirmButtonColor: '#217ac8'}).then(()=>location.reload()); - }else{ - swal.fire(resp, "", "error").then(); + window?.ppomPopup?.open({ + title: window?.ppom_vars?.i18n.popup.finishTitle, + hideCloseBtn: true, + onConfirmation: () => location.reload(), + onClose: () => location.reload() + }); + } else { + window?.ppomPopup?.open({ + title: window.ppom_vars.i18n.popup.errorTitle, + text: resp, + hideCloseBtn: true + }); } }); - }); + } + }) } @@ -122,34 +124,38 @@ jQuery(function($){ **/ $('body').on('click','a.ppom-delete-single-product', function(e){ e.preventDefault(); - var productmeta_id = $(this).attr('data-product-id'); - - swal.fire({ - title: "Are you sure?", - showCancelButton: true, - confirmButtonColor: "#DD6B55 ", - cancelButtonColor: "#DD6B55", - confirmButtonText: "Yes", - cancelButtonText: "No", - }).then( (result ) => { - if (!result.isConfirmed) return; + const productmeta_id = $(this).attr('data-product-id'); + + window?.ppomPopup?.open({ + title: window?.ppom_vars?.i18n.popup.confirmTitle, + onConfirmation: () => { $("#del-file-" + productmeta_id).html(''); - var data = { + const data = { action : 'ppom_delete_meta', productmeta_id : productmeta_id, ppom_meta_nonce : $("#ppom_meta_nonce").val() }; - $.post(ajaxurl, data, function(resp){ + $.post( ajaxurl, data, function(resp){ $("#del-file-" + productmeta_id).html(''); - if (resp.status === 'success') { - swal.fire({title: "Done", text: resp.message, type: "success" ,confirmButtonColor: '#217ac8'}).then(()=>location.reload()); - }else{ - swal.fire(resp.message, "", "error"); + if ( resp.status === 'success' ) { + window?.ppomPopup?.open({ + title: window?.ppom_vars?.i18n.popup.finishTitle, + hideCloseBtn: true, + onConfirmation: () => location.reload(), + onClose: () => location.reload() + }); + } else { + window?.ppomPopup?.open({ + title: window.ppom_vars.i18n.popup.errorTitle, + text: resp.message, + hideCloseBtn: true, + }); } }); - }); + } + }) }); $(document).on( 'change', '#ppom-bulk-actions', function(){ @@ -160,7 +166,11 @@ jQuery(function($){ }).get(); if ( ! ( checkedProducts_ids.length > 0 ) ) { - swal.fire("Please at least check one Meta!", "", "error"); + window?.ppomPopup?.open({ + title: window?.ppom_vars?.i18n.popup.confirmTitle, + type: 'error', + hideCloseBtn: true + }); return; } diff --git a/js/popup.js b/js/popup.js new file mode 100644 index 00000000..b778cbae --- /dev/null +++ b/js/popup.js @@ -0,0 +1,102 @@ +// @ts-check + +class PpomPopup { + constructor() { + this.overlay = document.createElement('div'); + this.overlay.classList.add('ppom-popup-overlay'); + + // Close on outside click. + this.overlay.addEventListener('click', (event) => { + if ( event.target === this.overlay ) { + this.close(); + } + }); + + this.popup = document.createElement('div'); + this.popup.classList.add('ppom-popup'); + + this.container = document.createElement('div'); + this.container.classList.add('ppom-popup-container'); + + this.title = document.createElement('h2'); + this.title.classList.add('ppom-popup-title'); + + this.text = document.createElement('p'); + this.text.classList.add('ppom-popup-text'); + + const containerActions = document.createElement('div'); + containerActions.classList.add('ppom-popup-actions'); + + this.confirmButton = document.createElement('button'); + this.confirmButton.classList.add('ppom-btn-confirm') + this.confirmButton.textContent = window.ppom_vars.i18n.popup.confirmationBtn; + this.confirmButton.addEventListener('click', this.confirm.bind(this)); + + this.cancelButton = document.createElement('button'); + this.cancelButton.classList.add('ppom-btn-cancel') + this.cancelButton.textContent = window.ppom_vars.i18n.popup.cancelBtn; + this.cancelButton.addEventListener('click', this.close.bind(this)); + + containerActions.appendChild(this.cancelButton); + containerActions.appendChild(this.confirmButton); + + this.container.appendChild(this.title); + this.container.appendChild(this.text); + this.container.appendChild(containerActions); + this.popup.appendChild(this.container); + this.overlay.appendChild(this.popup); + + this.onConfirmation = () => {} + this.onClose = () => {} + } + + open( options = {} ) { + + if ( options?.title ) { + this.title.innerHTML = options.title; + } + + if ( options?.text ) { + this.text.innerHTML = options.text; + } + + if ( options?.onConfirmation ) { + this.onConfirmation = options.onConfirmation; + } + + if ( options?.onClose ) { + this.onClose = options.onClose; + } + + this.cancelButton.classList.toggle('ppom-hide', Boolean( options?.hideCloseBtn ) ); + this.text.classList.toggle('ppom-hide', Boolean( options?.text?.length ) ); + this.popup.classList.toggle('ppom-error', 'error' === options?.type ); + + this.show(); + } + + close() { + this.hide(); + this.onClose?.(); + } + + confirm() { + this.hide(); + this.onConfirmation?.(); + } + + show() { + document.body.appendChild(this.overlay); + } + + hide() { + document.body.removeChild(this.overlay); + } +} + +window.addEventListener('DOMContentLoaded', () => { + /** + * @type {import('../global.d.ts').Popup} + */ + window.ppomPopup = new PpomPopup(); +}); \ No newline at end of file From 66bf9e84f558c30125cc92427d4dfe378a88276b Mon Sep 17 00:00:00 2001 From: "Soare Robert Daniel (Mac 2023)" Date: Tue, 3 Sep 2024 17:21:03 +0300 Subject: [PATCH 02/31] fix: add max image selection constrain to Image Field --- js/ppom.inputs.js | 48 +++++++++++++++++++++++------ templates/frontend/inputs/image.php | 11 ++++--- 2 files changed, 45 insertions(+), 14 deletions(-) diff --git a/js/ppom.inputs.js b/js/ppom.inputs.js index 4a20ae0c..e3b63699 100644 --- a/js/ppom.inputs.js +++ b/js/ppom.inputs.js @@ -167,18 +167,46 @@ function ppom_init_js_for_ppom_fields(ppom_fields) { jQuery('.ppom-zoom-' + img_id).imageTooltip(); } - jQuery('.ppom-image-select input.ppom-input.image').click(function(){ - const multiple = jQuery(this).data('allow-multiple'); + document.querySelectorAll('.ppom-image-select').forEach( ( /** @type{HTMLDivElement} */ container ) => { - if( multiple ) { - return; - } - - if( jQuery(this).data('required') ) { - jQuery(this).prop('checked', true); - } + /** + * @type {HTMLInputElement[]} Holds the selected images. + */ + const selectedImgs = []; - jQuery(this).parents('.ppom-image-select').find('input.ppom-input.image').not(this).prop('checked', false); + container.querySelectorAll('.pre_upload_image').forEach( (/** @type{HTMLDivElement} */ inputContainer) => { + const input = inputContainer.querySelector('input'); + if ( ! input ) { + return; + } + + const multiple = input.dataset.allowMultiple; + + if ( ! multiple ) { + if (input.dataset.required) { + input.checked = true; + } + + const siblings = Array.from(input.parentNode.parentNode.querySelectorAll('input.ppom-input.image')); + siblings.filter(sibling => sibling !== input).forEach(sibling => sibling.checked = false); + } else { + const maxImgSelection = parseInt( input.dataset?.maxSelection ?? '0' ); + if ( maxImgSelection ) { + inputContainer.querySelector('img')?.addEventListener( 'click', () => { + selectedImgs.push( input ); + + while( selectedImgs.length > maxImgSelection ) { + const oldestImgSelected = selectedImgs.shift(); + if ( oldestImgSelected ) { + oldestImgSelected.checked = false; + } + } + }) + + } + } + + }); }); // Data Tooltip diff --git a/templates/frontend/inputs/image.php b/templates/frontend/inputs/image.php index 44f1213d..bad7223a 100644 --- a/templates/frontend/inputs/image.php +++ b/templates/frontend/inputs/image.php @@ -13,10 +13,11 @@ if ( ! defined( 'ABSPATH' ) ) { exit; } -$fm = new PPOM_InputManager( $field_meta, 'image' ); -$legacy_view = $fm->get_meta_value( 'legacy_view' ); -$multiple_allowed = $fm->get_meta_value( 'multiple_allowed' ); -$show_popup = $fm->get_meta_value( 'show_popup' ); +$fm = new PPOM_InputManager( $field_meta, 'image' ); +$legacy_view = $fm->get_meta_value( 'legacy_view' ); +$multiple_allowed = $fm->get_meta_value( 'multiple_allowed' ); +$show_popup = $fm->get_meta_value( 'show_popup' ); +$max_img_selection = $fm->get_meta_value( 'max_checked' ); $required = isset($field_meta['required']) && $field_meta['required'] === 'on'; $input_classes = $fm->input_classes(); @@ -122,6 +123,7 @@ class="" data-optionid="" data-data_name="data_name() ); ?>" value="" + data-max-selected="" > @@ -223,6 +225,7 @@ class="" data-optionid="" data-data_name="data_name() ); ?>" value="" + data-max-selection="" data-allow-multiple="yes" data-required="yes" From c431eaf4f631d934b3950d2dae89eabec76adefb Mon Sep 17 00:00:00 2001 From: girishpanchal30 Date: Fri, 6 Sep 2024 16:50:55 +0530 Subject: [PATCH 03/31] Fix compatibility with multisite --- woocommerce-product-addon.php | 47 +++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/woocommerce-product-addon.php b/woocommerce-product-addon.php index 48670e90..13973d2f 100644 --- a/woocommerce-product-addon.php +++ b/woocommerce-product-addon.php @@ -163,5 +163,48 @@ function () { } ); -register_activation_hook( __FILE__, array( 'NM_PersonalizedProduct', 'activate_plugin' ) ); -register_deactivation_hook( __FILE__, array( 'NM_PersonalizedProduct', 'deactivate_plugin' ) ); +/** + * Plugin activation. + * + * @param bool $network_wide Whether the plugin is network deactivated or not. + */ +function ppom_activation( $network_wide ) { + if ( is_multisite() && $network_wide ) { + $site_ids = get_sites( + array( + 'fields' => 'ids', + ) + ); + foreach ( $site_ids as $site_id ) { + switch_to_blog( $site_id ); + NM_PersonalizedProduct::activate_plugin(); + restore_current_blog(); + } + } else { + NM_PersonalizedProduct::activate_plugin(); + } +} +register_activation_hook( __FILE__, 'ppom_activation' ); + +/** + * Plugin deactivation. + * + * @param bool $network_wide Whether the plugin is network deactivated or not. + */ +function ppom_deactivation( $network_wide ) { + if ( is_multisite() && $network_wide ) { + $site_ids = get_sites( + array( + 'fields' => 'ids', + ) + ); + foreach ( $site_ids as $site_id ) { + switch_to_blog( $site_id ); + NM_PersonalizedProduct::deactivate_plugin(); + restore_current_blog(); + } + } else { + NM_PersonalizedProduct::deactivate_plugin(); + } +} +register_deactivation_hook( __FILE__, 'ppom_deactivation' ); From eca4d42f56215079d7ba5fdec639af1507631434 Mon Sep 17 00:00:00 2001 From: girishpanchal30 Date: Fri, 6 Sep 2024 17:19:46 +0530 Subject: [PATCH 04/31] Fix conditional field issue with other languages --- inc/hooks.php | 2 +- js/ppom-conditions-v2.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/inc/hooks.php b/inc/hooks.php index f26474c8..1abe0f2a 100644 --- a/inc/hooks.php +++ b/inc/hooks.php @@ -705,7 +705,7 @@ function ppom_hooks_input_main_wrapper_class( $wrapper_class, $classes_array, $f foreach ( $conditions['rules'] as $index => $rule ) { - $element = isset( $rule['elements'] ) ? $rule['elements'] : ''; + $element = isset( $rule['elements'] ) ? strtolower( $rule['elements'] ): ''; $wrapper_class .= " ppom-cond-{$element}"; $wrapper_class .= " ppom-locked-{$element}"; } diff --git a/js/ppom-conditions-v2.js b/js/ppom-conditions-v2.js index db05c908..5e8296c0 100644 --- a/js/ppom-conditions-v2.js +++ b/js/ppom-conditions-v2.js @@ -291,7 +291,7 @@ function ppom_check_conditions(data_name, callback) { let cond_elements = []; for (var t = 1; t <= total_cond; t++) { - const cond_element = jQuery(this).data(`cond-input${t}`); + const cond_element = jQuery(this).data(`cond-input${t}`)?.toString()?.toLowerCase(); const cond_val = jQuery(this).data(`cond-val${t}`).toString(); const operator = jQuery(this).data(`cond-operator${t}`); const field_val = ppom_get_element_value(cond_element); From d7d1206bc716f1bb9c78da06c941891648227acf Mon Sep 17 00:00:00 2001 From: girishpanchal30 Date: Fri, 6 Sep 2024 17:54:44 +0530 Subject: [PATCH 05/31] Create db table on the admin_init hook --- classes/admin.class.php | 13 ++++++++++ woocommerce-product-addon.php | 47 ++--------------------------------- 2 files changed, 15 insertions(+), 45 deletions(-) diff --git a/classes/admin.class.php b/classes/admin.class.php index bae49c7a..b967f81a 100644 --- a/classes/admin.class.php +++ b/classes/admin.class.php @@ -86,6 +86,8 @@ function __construct() { 10 ); + add_action( 'admin_init', array( $this, 'ppom_create_db_tables' ) ); + } @@ -412,5 +414,16 @@ public function load_admin_menu() { PPOM_Survey::get_instance()->init(); } + /** + * Create database tables. + */ + public function ppom_create_db_tables() { + if ( ! empty( get_option( 'personalizedproduct_db_version' ) ) ) { + return; + } + + NM_PersonalizedProduct::activate_plugin(); + } + } diff --git a/woocommerce-product-addon.php b/woocommerce-product-addon.php index 13973d2f..48670e90 100644 --- a/woocommerce-product-addon.php +++ b/woocommerce-product-addon.php @@ -163,48 +163,5 @@ function () { } ); -/** - * Plugin activation. - * - * @param bool $network_wide Whether the plugin is network deactivated or not. - */ -function ppom_activation( $network_wide ) { - if ( is_multisite() && $network_wide ) { - $site_ids = get_sites( - array( - 'fields' => 'ids', - ) - ); - foreach ( $site_ids as $site_id ) { - switch_to_blog( $site_id ); - NM_PersonalizedProduct::activate_plugin(); - restore_current_blog(); - } - } else { - NM_PersonalizedProduct::activate_plugin(); - } -} -register_activation_hook( __FILE__, 'ppom_activation' ); - -/** - * Plugin deactivation. - * - * @param bool $network_wide Whether the plugin is network deactivated or not. - */ -function ppom_deactivation( $network_wide ) { - if ( is_multisite() && $network_wide ) { - $site_ids = get_sites( - array( - 'fields' => 'ids', - ) - ); - foreach ( $site_ids as $site_id ) { - switch_to_blog( $site_id ); - NM_PersonalizedProduct::deactivate_plugin(); - restore_current_blog(); - } - } else { - NM_PersonalizedProduct::deactivate_plugin(); - } -} -register_deactivation_hook( __FILE__, 'ppom_deactivation' ); +register_activation_hook( __FILE__, array( 'NM_PersonalizedProduct', 'activate_plugin' ) ); +register_deactivation_hook( __FILE__, array( 'NM_PersonalizedProduct', 'deactivate_plugin' ) ); From 1aeeca1a1142a140d6cb00006278afd2dbd341c4 Mon Sep 17 00:00:00 2001 From: girishpanchal30 Date: Mon, 9 Sep 2024 12:28:59 +0530 Subject: [PATCH 06/31] Hide unsupported field option tabs --- js/admin/ppom-admin.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/js/admin/ppom-admin.js b/js/admin/ppom-admin.js index 23f5c1d9..8d4724f4 100644 --- a/js/admin/ppom-admin.js +++ b/js/admin/ppom-admin.js @@ -436,7 +436,18 @@ jQuery(function($) { var field_model_id = 'ppom_field_model_' + field_no + ''; - clone_new_field.find('.ppom_save_fields_model').end().appendTo('.ppom_save_fields_model').attr('id', field_model_id); + clone_new_field.find('.ppom_save_fields_model') + .end() + .appendTo('.ppom_save_fields_model') + .attr('id', field_model_id) + .find( '.ppom-tabs-header label.ppom-tabs-label' ) + .each( function( index, item ) { + var tabId = $(item).attr('id'); + var hasTabOptions = $( '#' + field_model_id, document )?.find( '.ppom_handle_' + tabId )?.length > 0; + if ( ! hasTabOptions ) { + $(item).hide(); + } + } ); clone_new_field.find('.ppom-field-checker').attr('data-field-index', field_no); clone_new_field.find('.ppom-field-checker').addClass('ppom-add-fields-js-action'); From 6209414a189afb2b28f579921f00a4bf3b8e49c1 Mon Sep 17 00:00:00 2001 From: selul Date: Mon, 9 Sep 2024 14:10:02 +0300 Subject: [PATCH 07/31] add link to product actions --- classes/admin.class.php | 28 ++++++++++++++++++++++++++++ woocommerce-product-addon.php | 1 + 2 files changed, 29 insertions(+) diff --git a/classes/admin.class.php b/classes/admin.class.php index bae49c7a..144874fa 100644 --- a/classes/admin.class.php +++ b/classes/admin.class.php @@ -88,6 +88,34 @@ function __construct() { } + /** + * Add upgrade to pro plugin action link. + * + * @param array $actions Plugin actions. + * @param string $plugin_file Path to the plugin file relative to the plugins directory. + * + * @return array + */ + public function upgrade_to_pro_plugin_action( $actions, $plugin_file ) { + if ( apply_filters( 'product_ppom_license_status', '' ) === 'valid' || apply_filters( 'product_ppom_license_status', '' ) === 'active_expired' ) { + return $actions; + } + + return array_merge( + array( + 'upgrade_link' => '' . __( 'Get Pro', 'woocommerce-product-addon' ) . '', + ), + $actions + ); + + } /* * creating menu page for this plugin diff --git a/woocommerce-product-addon.php b/woocommerce-product-addon.php index 48670e90..a1600b6b 100644 --- a/woocommerce-product-addon.php +++ b/woocommerce-product-addon.php @@ -101,6 +101,7 @@ function ppom_i18n_setup() { $ppom_admin = new NM_PersonalizedProduct_Admin(); $ppom_basename = plugin_basename( __FILE__ ); add_filter( "plugin_action_links_{$ppom_basename}", 'ppom_settings_link', 10 ); + add_filter( "plugin_action_links_{$ppom_basename}", [ $ppom_admin, 'upgrade_to_pro_plugin_action' ], 10, 2 ); } function PPOM() { From dd8861ef26ff88b30c45e18ada41f4d4c53eb0c9 Mon Sep 17 00:00:00 2001 From: selul Date: Mon, 9 Sep 2024 14:31:10 +0300 Subject: [PATCH 08/31] translate link differently --- classes/admin.class.php | 2 +- classes/freemium.class.php | 2 +- classes/plugin.class.php | 2 +- inc/admin.php | 2 +- templates/admin/addons-list.php | 2 +- templates/admin/ppom-fields.php | 2 +- woocommerce-product-addon.php | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/classes/admin.class.php b/classes/admin.class.php index 144874fa..ce34a97e 100644 --- a/classes/admin.class.php +++ b/classes/admin.class.php @@ -109,7 +109,7 @@ public function upgrade_to_pro_plugin_action( $actions, $plugin_file ) { 'utm_medium' => 'plugins', 'utm_campaign' => 'rowaction', ), - PPOM_UPGRADE_URL + tsdk_translate_link( PPOM_UPGRADE_URL ) ) . '" title="' . __( 'More Features', 'woocommerce-product-addon' ) . '" target="_blank" rel="noopener noreferrer" style="color: #009E29; font-weight: 700;" onmouseover="this.style.color=\'#008a20\';" onmouseout="this.style.color=\'#009528\';" >' . __( 'Get Pro', 'woocommerce-product-addon' ) . '', ), $actions diff --git a/classes/freemium.class.php b/classes/freemium.class.php index 9e37a87b..3733e0ee 100644 --- a/classes/freemium.class.php +++ b/classes/freemium.class.php @@ -64,7 +64,7 @@ public function add_locked_cfr_tab( $tabs ) { */ public function get_freemium_cfr_content() { ob_start(); - $upgrade_url = tsdk_utmify( PPOM_UPGRADE_URL, 'lockedconditionalfield', 'ppompage' ); + $upgrade_url = tsdk_utmify( tsdk_translate_link( PPOM_UPGRADE_URL ), 'lockedconditionalfield', 'ppompage' ); ?>

diff --git a/classes/plugin.class.php b/classes/plugin.class.php index 426b587a..3244ed20 100644 --- a/classes/plugin.class.php +++ b/classes/plugin.class.php @@ -884,7 +884,7 @@ function show_wc_custom_message() { function ppom_export_meta() { // if( ppom_pro_is_installed() ) return ''; - $buy_pro = tsdk_utmify( PPOM_UPGRADE_URL, 'export-import', 'tryexport' ); + $buy_pro = tsdk_utmify( tsdk_translate_link( PPOM_UPGRADE_URL ), 'export-import', 'tryexport' ); $args = array( 'link_url' => $buy_pro, 'link_text' => 'Buy now', diff --git a/inc/admin.php b/inc/admin.php index 6cc430b5..e27764d1 100644 --- a/inc/admin.php +++ b/inc/admin.php @@ -714,7 +714,7 @@ function ppom_admin_bar_menu() { function ppom_admin_update_pro_notice() { - $buy_paddle = tsdk_utmify( PPOM_UPGRADE_URL, 'addmorefields', 'ppompage' ); + $buy_paddle = tsdk_utmify( tsdk_translate_link( PPOM_UPGRADE_URL ), 'addmorefields', 'ppompage' ); echo '
'; echo '' . __( 'Add more field types', 'woocommerce-product-addon' ) . ''; diff --git a/templates/admin/addons-list.php b/templates/admin/addons-list.php index 415c5623..ad1bd4ee 100644 --- a/templates/admin/addons-list.php +++ b/templates/admin/addons-list.php @@ -61,7 +61,7 @@
- Get Pro + Get Pro '#313350', // optional 'pages' => [ 'woocommerce_page_ppom' ], //pages where the float widget should be displayed 'has_upgrade_menu' => ! defined( 'PPOM_PRO_PATH' ), - 'upgrade_link' => tsdk_utmify( PPOM_UPGRADE_URL, 'float_widget' ), + 'upgrade_link' => tsdk_utmify( tsdk_translate_link( PPOM_UPGRADE_URL ), 'float_widget' ), 'documentation_link' => 'https://rviv.ly/C1cmSQ', 'premium_support_link' => defined( 'PPOM_PRO_PATH' ) ? tsdk_translate_link( tsdk_support_link( PPOM_PRO_PATH . '/ppom.php' ) ) : '', 'feature_request_link' => tsdk_translate_link( 'https://store.themeisle.com/suggest-a-feature/' ), From 76884766ec19d6e00326ecdf42df922c8734ffd8 Mon Sep 17 00:00:00 2001 From: girishpanchal30 Date: Mon, 9 Sep 2024 17:19:39 +0530 Subject: [PATCH 09/31] Improve the 'Existing Product Meta' button --- templates/admin/ppom-fields.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/templates/admin/ppom-fields.php b/templates/admin/ppom-fields.php index 192d0a40..8ac92375 100644 --- a/templates/admin/ppom-fields.php +++ b/templates/admin/ppom-fields.php @@ -51,7 +51,7 @@ ) ); -echo '

' . __( '« Existing Product Meta', 'woocommerce-product-addon' ) . '

'; +echo '

' . __( '« Existing Product Meta', 'woocommerce-product-addon' ) . '

'; $product_id = isset( $_GET['product_id'] ) ? intval( $_GET['product_id'] ) : ''; @@ -412,10 +412,6 @@ class="dashicons dashicons-edit">
-

-

-
render_field_settings(); ?>
From 7bd2dc16bac748ead3f944477428e039f10d9426 Mon Sep 17 00:00:00 2001 From: girishpanchal30 Date: Mon, 9 Sep 2024 18:13:04 +0530 Subject: [PATCH 10/31] Add javascript unsaved warning --- js/admin/ppom-admin.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/js/admin/ppom-admin.js b/js/admin/ppom-admin.js index 23f5c1d9..43c11516 100644 --- a/js/admin/ppom-admin.js +++ b/js/admin/ppom-admin.js @@ -1356,6 +1356,29 @@ jQuery(function($) { $(clone_new_field).find('input[data-metatype="jquery_dp"]').change(toggleHandler.activateHandler); } ); + // Unsaved form exit confirmation. + var unsaved = false; + $( ':input' ).change(function () { + if ( $( this ).parents( '.ppom-checkboxe-style' )?.length > 0 ) { + unsaved = false; + return; + } + unsaved = true; + }); + $( '.ppom-submit-btn input.btn, button.ppom_copy_field' ).on( 'click', function() { + if ( $(this).hasClass('ppom_copy_field') ) { + unsaved = true; + return; + } + unsaved = false; + } ); + window.addEventListener( 'beforeunload', function( e ) { + if ( unsaved ) { + e.preventDefault(); + e.returnValue = ''; + } + }); + $(document).ready(function(){ $('.ppom-slider').each(function(i, item){ const itemEl = $(item); From c0d50aed58c86a482a725a492f010d79ba92299e Mon Sep 17 00:00:00 2001 From: girishpanchal30 Date: Mon, 9 Sep 2024 18:28:37 +0530 Subject: [PATCH 11/31] Fix issue with new field --- js/admin/ppom-admin.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/admin/ppom-admin.js b/js/admin/ppom-admin.js index 43c11516..93bab193 100644 --- a/js/admin/ppom-admin.js +++ b/js/admin/ppom-admin.js @@ -1365,8 +1365,8 @@ jQuery(function($) { } unsaved = true; }); - $( '.ppom-submit-btn input.btn, button.ppom_copy_field' ).on( 'click', function() { - if ( $(this).hasClass('ppom_copy_field') ) { + $( document ).on( 'click', '.ppom-submit-btn input.btn, button.ppom_copy_field, button.ppom-add-fields-js-action', function() { + if ( $(this).hasClass('ppom_copy_field') || $(this).hasClass( 'ppom-add-fields-js-action' ) ) { unsaved = true; return; } From 8d869b116d80c4839cd15c5b3448df1ca72a80bc Mon Sep 17 00:00:00 2001 From: girishpanchal30 Date: Tue, 10 Sep 2024 11:29:49 +0530 Subject: [PATCH 12/31] Disable pointer events on input labels --- css/ppom-admin.css | 3 +++ 1 file changed, 3 insertions(+) diff --git a/css/ppom-admin.css b/css/ppom-admin.css index ecef0789..fc006b3a 100644 --- a/css/ppom-admin.css +++ b/css/ppom-admin.css @@ -1163,4 +1163,7 @@ a[data-modal-id="ppom-nm-plugins-modal"] { #ppom-admin-changelog-header-top { padding: 15px 30px 0 0; +} +.ppom-wrapper label { + cursor: auto; } \ No newline at end of file From 955fdce048eaed966afd8e036ef637c46dcdd263 Mon Sep 17 00:00:00 2001 From: girishpanchal30 Date: Tue, 10 Sep 2024 12:10:32 +0530 Subject: [PATCH 13/31] Disable field conditions when they are not enabled --- css/ppom-admin.css | 5 +++++ js/admin/ppom-admin.js | 31 ++++++++++++++++++++++++------- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/css/ppom-admin.css b/css/ppom-admin.css index ecef0789..b45d6412 100644 --- a/css/ppom-admin.css +++ b/css/ppom-admin.css @@ -1163,4 +1163,9 @@ a[data-modal-id="ppom-nm-plugins-modal"] { #ppom-admin-changelog-header-top { padding: 15px 30px 0 0; +} + +.ppom-disabled-overlay { + opacity: 0.6; + pointer-events: none; } \ No newline at end of file diff --git a/js/admin/ppom-admin.js b/js/admin/ppom-admin.js index 93bab193..15c64e28 100644 --- a/js/admin/ppom-admin.js +++ b/js/admin/ppom-admin.js @@ -1357,27 +1357,44 @@ jQuery(function($) { } ); // Unsaved form exit confirmation. - var unsaved = false; - $( ':input' ).change(function () { + var unsaved = false; + $( ':input' ).change(function () { if ( $( this ).parents( '.ppom-checkboxe-style' )?.length > 0 ) { unsaved = false; return; } unsaved = true; - }); - $( document ).on( 'click', '.ppom-submit-btn input.btn, button.ppom_copy_field, button.ppom-add-fields-js-action', function() { + }); + $( document ).on( 'click', '.ppom-submit-btn input.btn, button.ppom_copy_field, button.ppom-add-fields-js-action', function() { if ( $(this).hasClass('ppom_copy_field') || $(this).hasClass( 'ppom-add-fields-js-action' ) ) { unsaved = true; return; } unsaved = false; - } ); - window.addEventListener( 'beforeunload', function( e ) { + } ); + window.addEventListener( 'beforeunload', function( e ) { if ( unsaved ) { e.preventDefault(); e.returnValue = ''; + } + }); + + $( document ).on( 'ppom_fields_tab_changed', function(e, id, tab) { + if ( 'condition_tab' !== id ) { + return; } - }); + + if ( ! $('input[data-metatype="logic"]', tab?.first() )?.is(':checked') ) { + tab?.last()?.addClass( 'ppom-disabled-overlay' ); + } + } ); + + $( document ).on( 'change', 'input[data-metatype="logic"]:visible', function() { + $(this) + .parents('.ppom_handle_condition_tab') + .next('.ppom_handle_condition_tab') + .toggleClass('ppom-disabled-overlay'); + } ); $(document).ready(function(){ $('.ppom-slider').each(function(i, item){ From b99a8628eb60a9c079cb107d3b4736a229996f0b Mon Sep 17 00:00:00 2001 From: girishpanchal30 Date: Tue, 10 Sep 2024 12:43:42 +0530 Subject: [PATCH 14/31] Lock the data name field on edit mode --- js/admin/ppom-admin.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/js/admin/ppom-admin.js b/js/admin/ppom-admin.js index 15c64e28..5cf6b7fb 100644 --- a/js/admin/ppom-admin.js +++ b/js/admin/ppom-admin.js @@ -266,7 +266,8 @@ jQuery(function($) { event.preventDefault(); var the_id = $(this).attr('id'); - $('#ppom_field_model_' + the_id + '').find('.ppom-close-checker').removeClass('ppom-close-fields'); + $('#ppom_field_model_' + the_id).find('.ppom-close-checker').removeClass('ppom-close-fields'); + $('#ppom_field_model_' + the_id).find('input[data-metatype="data_name"]').attr('readonly', true); }); @@ -990,7 +991,7 @@ jQuery(function($) { if (wp_field == 'shipping_fields' || wp_field == 'billing_fields') { return; } - selector.find('[data-meta-id="data_name"] input[type="text"]').val(field_id); + selector.find('[data-meta-id="data_name"] input[type="text"]:not([readonly])').val(field_id); }); From 806672a3cbc245f6c1cb831089a528908f976ec3 Mon Sep 17 00:00:00 2001 From: girishpanchal30 Date: Tue, 10 Sep 2024 16:21:21 +0530 Subject: [PATCH 15/31] Remove readonly attr and lock the data name --- js/admin/ppom-admin.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/js/admin/ppom-admin.js b/js/admin/ppom-admin.js index 5cf6b7fb..aba0a48d 100644 --- a/js/admin/ppom-admin.js +++ b/js/admin/ppom-admin.js @@ -262,12 +262,13 @@ jQuery(function($) { /** 9- Edit Existing Fields **/ + var lockedDataName = false; $(document).on('click', '.ppom-edit-field', function(event) { event.preventDefault(); var the_id = $(this).attr('id'); $('#ppom_field_model_' + the_id).find('.ppom-close-checker').removeClass('ppom-close-fields'); - $('#ppom_field_model_' + the_id).find('input[data-metatype="data_name"]').attr('readonly', true); + lockedDataName = true; }); @@ -991,6 +992,9 @@ jQuery(function($) { if (wp_field == 'shipping_fields' || wp_field == 'billing_fields') { return; } + if ( true === lockedDataName ) { + return; + } selector.find('[data-meta-id="data_name"] input[type="text"]:not([readonly])').val(field_id); }); From a49b680c515d835599dad7e1373181229c4d03f7 Mon Sep 17 00:00:00 2001 From: girishpanchal30 Date: Tue, 10 Sep 2024 18:56:13 +0530 Subject: [PATCH 16/31] Improve field groups page upsells --- classes/admin.class.php | 1 - classes/fields.class.php | 1 - css/ppom-admin.css | 35 +++++++++++++++++++++++++++++++ inc/admin.php | 9 -------- js/admin/ppom-admin.js | 4 ++++ js/admin/ppom-meta-table.js | 2 +- templates/admin/existing-meta.php | 15 +++++++++++++ 7 files changed, 55 insertions(+), 12 deletions(-) diff --git a/classes/admin.class.php b/classes/admin.class.php index ce34a97e..4463e8f5 100644 --- a/classes/admin.class.php +++ b/classes/admin.class.php @@ -72,7 +72,6 @@ function __construct() { // adding wpml support for PPOM Settings add_filter( 'woocommerce_admin_settings_sanitize_option', array( $this, 'ppom_setting_wpml' ), 10, 3 ); - add_action( 'ppom_pdf_setting_action', 'ppom_admin_update_pro_notice', 10 ); add_action( 'admin_head', array( $this, 'ppom_tabs_custom_style' ) ); diff --git a/classes/fields.class.php b/classes/fields.class.php index 3096cba2..d2892943 100644 --- a/classes/fields.class.php +++ b/classes/fields.class.php @@ -163,7 +163,6 @@ function load_script( $hook ) { 'exportLabel'=>esc_html__( 'Export', 'woocommerce-product-addon' ), 'exportLockedLabel'=>esc_html__( 'Export (PRO)', 'woocommerce-product-addon' ), 'importLabel'=>esc_html__( 'Import Field Groups ', 'woocommerce-product-addon' ), - 'importLockedLabel'=>esc_html__( 'Import Field Groups (PRO)', 'woocommerce-product-addon' ), 'freemiumCFRContent' => \PPOM_Freemium::get_instance()->get_freemium_cfr_content(), 'freemiumCFRTab' => \PPOM_Freemium::TAB_KEY_FREEMIUM_CFR, 'popup' => [ diff --git a/css/ppom-admin.css b/css/ppom-admin.css index 3b80a04d..a323aae2 100644 --- a/css/ppom-admin.css +++ b/css/ppom-admin.css @@ -1255,4 +1255,39 @@ a[data-modal-id="ppom-nm-plugins-modal"] { .ppom-wrapper label { cursor: auto; +} + +#ppom-import-upsell{ + text-align: center; + width: 600px; +} +#ppom-import-upsell .ppom-modal-body{ + position: relative; + padding: 30px; +} +#ppom-import-upsell button.close-model { + position: absolute; + right: 10px; + top: 10px; + background: transparent; + border: 0; + padding: 0; + font-size: 20px; +} + +#ppom-import-upsell .ppom-lock-icon { + padding-bottom: 30px; +} + +#ppom-import-upsell .ppom-lock-icon .dashicons { + width: 48px; + height: 48px; + font-size: 48px; +} + +#ppom-import-upsell p { + font-size: 16px; + text-align: left; + padding-bottom: 10px; + padding-top: 20px; } \ No newline at end of file diff --git a/inc/admin.php b/inc/admin.php index e27764d1..2c653b93 100644 --- a/inc/admin.php +++ b/inc/admin.php @@ -711,12 +711,3 @@ function ppom_admin_bar_menu() { ); } } - -function ppom_admin_update_pro_notice() { - - $buy_paddle = tsdk_utmify( tsdk_translate_link( PPOM_UPGRADE_URL ), 'addmorefields', 'ppompage' ); - - echo ''; -} diff --git a/js/admin/ppom-admin.js b/js/admin/ppom-admin.js index 88c15cea..f41d1abf 100644 --- a/js/admin/ppom-admin.js +++ b/js/admin/ppom-admin.js @@ -117,6 +117,10 @@ jQuery(function($) { **/ $('.ppom-import-export-btn').on('click', function(event) { event.preventDefault(); + if ( $(".ppom-import-export-block").length === 0 ) { + $('#ppom-import-upsell').fadeIn(); + return; + } $('.ppom-more-plugins-block').hide(); $(".ppom-import-export-block").show(); $(".ppom-product-meta-block").hide(); diff --git a/js/admin/ppom-meta-table.js b/js/admin/ppom-meta-table.js index bc6fc44f..0590144f 100644 --- a/js/admin/ppom-meta-table.js +++ b/js/admin/ppom-meta-table.js @@ -185,7 +185,7 @@ jQuery(function($){ const exportOption = ppom_vars.ppomProActivated === 'yes' ? `` : ``; - const importBtn = ppom_vars.ppomProActivated === 'yes' ? `${ppom_vars.i18n.importLabel}` : `${ppom_vars.i18n.importLockedLabel}`; + const importBtn = `${ppom_vars.i18n.importLabel}`; const bulkActions = ` + +
+

selector

+

+
+

From 158a1657a8e8067e17bdafea29bf9e7928679f66 Mon Sep 17 00:00:00 2001 From: girishpanchal30 Date: Thu, 12 Sep 2024 16:55:46 +0530 Subject: [PATCH 26/31] Add default field block wrapper selector --- templates/admin/ppom-fields.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/templates/admin/ppom-fields.php b/templates/admin/ppom-fields.php index 7dd192a0..b06014f7 100644 --- a/templates/admin/ppom-fields.php +++ b/templates/admin/ppom-fields.php @@ -37,7 +37,7 @@ $send_file_attachment = ( isset( $ppom_settings->send_file_attachment ) ? $ppom_settings->send_file_attachment : '' ); $show_cart_thumb = ( isset( $ppom_settings->show_cart_thumb ) ? $ppom_settings->show_cart_thumb : '' ); $aviary_api_key = ( isset( $ppom_settings->aviary_api_key ) ? $ppom_settings->aviary_api_key : '' ); - $productmeta_style = ( isset( $ppom_settings->productmeta_style ) ? $ppom_settings->productmeta_style : '' ); + $productmeta_style = ! empty( $ppom_settings->productmeta_style ) ? $ppom_settings->productmeta_style : ".ppom-id-$product_meta_id {\n}\n"; $productmeta_js = ( isset( $ppom_settings->productmeta_js ) ? $ppom_settings->productmeta_js : '' ); $productmeta_categories = ( isset( $ppom_settings->productmeta_categories ) ? $ppom_settings->productmeta_categories : '' ); $product_meta = json_decode( $ppom_settings->the_meta, true ); @@ -197,11 +197,11 @@ class="dashicons dashicons-editor-help"> title=""> - +
-

selector

+

.ppom-id-

-
+

From 04f709d2aaf017728ca44422bd2600303cd6e603 Mon Sep 17 00:00:00 2001 From: girishpanchal30 Date: Thu, 12 Sep 2024 17:39:55 +0530 Subject: [PATCH 27/31] Add selector keyword support --- classes/ppom.class.php | 1 + templates/admin/ppom-fields.php | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/classes/ppom.class.php b/classes/ppom.class.php index 78691342..3a8ce5d3 100644 --- a/classes/ppom.class.php +++ b/classes/ppom.class.php @@ -444,6 +444,7 @@ function inline_css() { if ( $this->ppom_settings->productmeta_style != '' ) { $inline_css = stripslashes( strip_tags( $this->ppom_settings->productmeta_style ) ); + $inline_css = str_replace( 'selector', ".ppom-id-$this->meta_id", $inline_css ); } return apply_filters( 'ppom_inline_css', $inline_css, $this ); diff --git a/templates/admin/ppom-fields.php b/templates/admin/ppom-fields.php index b06014f7..b991e09d 100644 --- a/templates/admin/ppom-fields.php +++ b/templates/admin/ppom-fields.php @@ -37,7 +37,7 @@ $send_file_attachment = ( isset( $ppom_settings->send_file_attachment ) ? $ppom_settings->send_file_attachment : '' ); $show_cart_thumb = ( isset( $ppom_settings->show_cart_thumb ) ? $ppom_settings->show_cart_thumb : '' ); $aviary_api_key = ( isset( $ppom_settings->aviary_api_key ) ? $ppom_settings->aviary_api_key : '' ); - $productmeta_style = ! empty( $ppom_settings->productmeta_style ) ? $ppom_settings->productmeta_style : ".ppom-id-$product_meta_id {\n}\n"; + $productmeta_style = ! empty( $ppom_settings->productmeta_style ) ? $ppom_settings->productmeta_style : "selector {\n}\n"; $productmeta_js = ( isset( $ppom_settings->productmeta_js ) ? $ppom_settings->productmeta_js : '' ); $productmeta_categories = ( isset( $ppom_settings->productmeta_categories ) ? $ppom_settings->productmeta_categories : '' ); $product_meta = json_decode( $ppom_settings->the_meta, true ); @@ -199,9 +199,9 @@ class="dashicons dashicons-editor-help">
-

.ppom-id-

+

selector

-
+

From 009ff95f2f9a0ff8a37dce401811e7e6cdf406be Mon Sep 17 00:00:00 2001 From: selul Date: Thu, 12 Sep 2024 22:00:54 +0300 Subject: [PATCH 28/31] review design of the settings page and add pro fields in read only mode --- backend/assets/settings.css | 71 ++- backend/options.php | 621 +++++++++++++++++++++++++++ backend/settings-panel.class.php | 7 +- backend/templates/admin-settings.php | 76 ++-- 4 files changed, 699 insertions(+), 76 deletions(-) diff --git a/backend/assets/settings.css b/backend/assets/settings.css index 8e5e23cc..6aa34d7c 100644 --- a/backend/assets/settings.css +++ b/backend/assets/settings.css @@ -1,6 +1,6 @@ /*--------------------------------- * Admin Settings Panel CSS - + * It included following css -> Inputs CSS -> Tooltip CSS @@ -45,11 +45,6 @@ transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; } -.nmsf-wrapper input[type="submit"] { - background: #f95700 !important; - border-color: #f95700 !important; - border-radius: 0 !important; -} .nmsf-migrate-back-btn { border-radius: 0 !important; @@ -289,15 +284,6 @@ /*Admin Settings Panel*/ -.nmsf-wrapper { - position: relative; - border: 1px solid #f957002b; - margin-right: 15px; - margin-top: 22px; - background-color: #eaeaea; - padding: 10px; - box-shadow: 0 1px 3px rgb(0 0 0 / 12%), 0 1px 2px rgb(0 0 0 / 24%); -} .nmsf-wrapper .nmsf-tabs-content div { padding: 15px 20px 15px 40px; @@ -355,6 +341,7 @@ div.nmsf-panels-area { margin: 0; padding: 0; transition: 0.5s all cubic-bezier(0.075, 0.82, 0.165, 1); + margin-left: 30px; } div.nmsf-panels-area .nmsf-panels-content { @@ -410,10 +397,10 @@ div.nmsf-panels-area .nmsf-panels-content p { padding: 8px 10px; margin-right: 2px; cursor: pointer; - background: #3985b7; font-weight: bold; transition: background ease 0.2s; - color: #fff; + border: 1px solid #c3c4c7; + background: #dcdcde; } .nmsf-panels-content-inner .nmsf-panel-settings-area { @@ -421,8 +408,6 @@ div.nmsf-panels-area .nmsf-panels-content p { flex-grow: 1; width: 100%; display: none; - padding: 1rem; - background: #fff; } .nmsf-panels-content-inner input[type=radio] { @@ -430,9 +415,10 @@ div.nmsf-panels-area .nmsf-panels-content p { } .nmsf-panels-content-inner input[type=radio]:checked+label { - background: #fff; - border-top: 2px solid #f95700; - color: #030303; + + border-bottom: 1px solid #f0f0f1; + background: #f0f0f1; + color: #000; } .nmsf-panels-content-inner input[type=radio]:checked+label+.nmsf-panel-settings-area { @@ -453,15 +439,10 @@ div.nmsf-panels-area .nmsf-panels-content p { background-color: transparent; } -.nmsf-panel-table tr { - border-top: 1px solid #f9570094; - border-bottom: 1px solid #f9570094; -} - .nmsf-panel-table td, .nmsf-panel-table th { - padding: .75rem; - vertical-align: top; + vertical-align: middle; + padding-left: 0px; } .nmsf-panel-table th { @@ -605,13 +586,9 @@ div.nmsf-panels-area .nmsf-panels-content p { } .nmsf-section-type h3 { - background-color: #F6F6F6; - margin: 0; - font-weight: 600; - font-family: 'Titillium Web', sans-serif; - font-size: 18px; - padding: 10px; - color: #0473AA; + color: #1d2327; + font-size: 1.3em; + margin: 1em 0; } .nmsf-hint-area { @@ -653,3 +630,25 @@ div.nmsf-panels-area .nmsf-panels-content p { color: #fff; background-color: #343a40; } +.ppom-is-locked-section{ + opacity: 0.7; +} +.ppom-is-locked-field .ppom-notice-upsell{ + font-style: italic; + font-weight: 500; +} +.ppom-is-locked-panel .ppom-notice-upsell { + background: #fff; + border: 1px solid #c3c4c7; + border-left-width: 4px; + box-shadow: 0 1px 1px rgba(0, 0, 0, .04); + border-left-color: #72aee6; + padding: 12px; + margin-top: 15px; +} +.ppom-is-locked-panel .nmsf-panel-desc, .ppom-is-locked-panel .nmsf-panel-table, .ppom-is-locked-field > * > *:not(.ppom-notice-upsell){ opacity: 0.6; cursor: not-allowed; } +.ppom-is-locked-panel input, +.ppom-is-locked-field input, +.ppom-is-locked-field select, +.ppom-is-locked-panel select{ cursor: not-allowed; + pointer-events: none; } \ No newline at end of file diff --git a/backend/options.php b/backend/options.php index 0bc34e33..f9878f92 100644 --- a/backend/options.php +++ b/backend/options.php @@ -127,3 +127,624 @@ */ PPOMSETTINGS()->register_tabs( $register_tabs )->register_panel( 'ppom_general_tab', $panel_meta ); PPOMSETTINGS()->register_setting( 'ppom_admin_core_settings', $core_settings ); +function ppom_load_pro_options() { + $pro_settings = array( + 'ppom_pro_basics' => array( + 'type' => 'section', + 'title' => __( 'Basic Settings', 'woocommerce-product-addon' ), + ), + 'ppom_hide_image_cart' => array( + 'type' => 'checkbox', + 'title' => __( 'Hide Images in Cart', 'woocommerce-product-addon' ), + 'desc' => __( 'When using image-type input, the selected images will not be displayed in the cart.', 'woocommerce-product-addon' ), + 'label' => __( 'Yes', 'woocommerce-product-addon' ), + ), + 'ppom_disable_crop_thumbnail' => array( + 'type' => 'checkbox', + 'title' => __( 'Uploaded Image Resize Proportionally', 'woocommerce-product-addon' ), + 'desc' => __( 'By default, images are resized into a square. Enable this option to resize uploaded images proportionally.', 'woocommerce-product-addon' ), + 'label' => __( 'Yes', 'woocommerce-product-addon' ), + ), + 'ppom_hide_clear_fields' => array( + 'type' => 'checkbox', + 'title' => __( 'Clear Fields After Add to Cart', 'woocommerce-product-addon' ), + 'desc' => __( 'Clear all fields on the product page after adding the item to the cart.', 'woocommerce-product-addon' ), + 'label' => __( 'Yes', 'woocommerce-product-addon' ), + ), + 'ppom_enable_client_validation' => array( + 'type' => 'checkbox', + 'title' => __( 'Enable Client-Side Validation', 'woocommerce-product-addon' ), + 'desc' => __( 'Enable this option for faster and more efficient validation of fields directly on the client side.', 'woocommerce-product-addon' ), + 'label' => __( 'Yes', 'woocommerce-product-addon' ), + ), + 'ppom_disable_meta_paypal_invoice' => array( + 'type' => 'checkbox', + 'title' => __( 'Do Not Send Product Meta to PayPal Invoice', 'woocommerce-product-addon' ), + 'desc' => __( 'Product meta will not be included in the PayPal invoice; only the item name will be sent to the invoice.', 'woocommerce-product-addon' ), + ), + 'ppom_label_select_option' => array( + 'type' => 'text', + 'title' => __( 'Shop Add to Cart Label', 'woocommerce-product-addon' ), + 'desc' => __( 'You can set the \'Add to Cart\' button label here when PPOM is attached.', 'woocommerce-product-addon' ), + 'default' => __( 'Select Options', 'woocommerce-product-addon' ), + ), + 'ppom_pro_pricing' => array( + 'type' => 'section', + 'title' => __( 'Price Settings', 'woocommerce-product-addon' ), + ), + 'ppom_override_product_price' => array( + 'type' => 'checkbox', + 'title' => __( 'Override Product Price', 'woocommerce-product-addon' ), + 'desc' => __( 'Override the core product price on archive and product pages if PPOM field options include a price.', 'woocommerce-product-addon' ), + 'label' => __( 'Yes', 'woocommerce-product-addon' ), + ), + 'ppom_hide_variable_product_price' => array( + 'type' => 'checkbox', + 'title' => __( 'Hide Variable Product Price', 'woocommerce-product-addon' ), + 'desc' => __( 'Hides the core price of variable products under the price title when PPOM fields are attached.', 'woocommerce-product-addon' ), + 'label' => __( 'Yes', 'woocommerce-product-addon' ), + ), + 'ppom_hide_option_price' => array( + 'type' => 'checkbox', + 'title' => __( 'Hide Options Price', 'woocommerce-product-addon' ), + 'desc' => __( 'Hides the option prices in Select, Radio, Checkbox, and Image inputs when displaying prices with labels.', 'woocommerce-product-addon' ), + 'label' => __( 'Yes', 'woocommerce-product-addon' ), + ), + 'ppom_taxable_option_price' => array( + 'type' => 'checkbox', + 'title' => __( 'Taxable Options Price', 'woocommerce-product-addon' ), + 'desc' => __( 'Apply tax settings to option prices as configured in WooCommerce → Tax.', 'woocommerce-product-addon' ), + 'label' => __( 'Yes', 'woocommerce-product-addon' ), + ), + 'ppom_taxable_fixed_price' => array( + 'type' => 'checkbox', + 'title' => __( 'Apply Tax on Fixed/Cart Fee', 'woocommerce-product-addon' ), + 'desc' => __( 'When this option is enabled, the fixed fee will be taxable.', 'woocommerce-product-addon' ), + 'label' => __( 'Yes', 'woocommerce-product-addon' ), + ), + 'ppom_price_table_location' => array( + 'type' => 'select', + 'title' => __( 'Price Table Position', 'woocommerce-product-addon' ), + 'desc' => __( 'Set the location where the price table will be rendered on the front end.', 'woocommerce-product-addon' ), + 'default' => 'after', + 'options' => array( + 'after' => __( 'After PPOM Fields', 'woocommerce-product-addon' ), + 'before' => __( 'Before PPOM Fields', 'woocommerce-product-addon' ), + ), + ), + 'ppom_pro_advanced' => array( + 'type' => 'section', + 'title' => __( 'Advanced Settings', 'woocommerce-product-addon' ), + ), + 'ppom_remove_unused_images_schedule' => array( + 'type' => 'select', + 'title' => __( 'Delete Unused Images', 'woocommerce-product-addon' ), + 'desc' => __( 'Set the duration for keeping uploaded images from abandoned carts. Reactivate the plugin after updating this option to apply changes.', 'woocommerce-product-addon' ), + 'default' => 'daily', + 'options' => array( + 'daily' => __( 'Daily', 'woocommerce-product-addon' ), + 'weekly' => __( 'Weekly', 'woocommerce-product-addon' ), + 'monthly' => __( 'Monthly', 'woocommerce-product-addon' ), + ), + ), + 'ppom_meta_overrides' => array( + 'type' => 'select', + 'title' => __( 'Meta Group Overrides', 'woocommerce-product-addon' ), + 'desc' => __( 'Leave this set to default if you\'re not sure.', 'woocommerce-product-addon' ), + 'default' => 'default', + 'options' => array( + 'default' => __( 'Default', 'woocommerce-product-addon' ), + 'category_override' => __( 'Category Overrides Individual Assignment', 'woocommerce-product-addon' ), + 'individual_override' => __( 'Individual Overrides Category Assignment', 'woocommerce-product-addon' ), + ), + ), + 'ppom_meta_priority' => array( + 'type' => 'select', + 'title' => __( 'Meta Group Priority', 'woocommerce-product-addon' ), + 'desc' => __( 'Choose which meta group takes priority when applied: Category or Product. Leave this set to default if you\'re not sure.', 'woocommerce-product-addon' ), + 'default' => 'default', + 'options' => array( + 'category_first' => __( 'Category First', 'woocommerce-product-addon' ), + 'individual_first' => __( 'Individual First', 'woocommerce-product-addon' ), + ), + ), + ); + + $style_settings = array( + 'ppom_styles_general_section' => array( + 'type' => 'section', + 'title' => __( 'General Settings', 'woocommerce-product-addon' ), + ), + 'ppom_input_label_style' => array( + 'type' => 'typography', + 'title' => __( 'Field Label', 'woocommerce-product-addon' ), + 'output' => '.ppom-wrapper label.form-control-label', + ), + 'ppom_input_desc_style' => array( + 'type' => 'typography', + 'title' => __( 'Field Description', 'woocommerce-product-addon' ), + 'output' => '.ppom-wrapper .ppom-input-desc', + ), + 'ppom_input_option_label_style' => array( + 'type' => 'typography', + 'title' => __( 'Options Label', 'woocommerce-product-addon' ), + 'output' => '.ppom-wrapper .ppom-input-option-label', + ), + 'ppom_input_option_price_label_style' => array( + 'type' => 'typography', + 'title' => __( 'Options Price Label', 'woocommerce-product-addon' ), + 'output' => '.ppom-wrapper .ppom-option-label-price', + ), + 'ppom_styles_advance_section' => array( + 'type' => 'section', + 'title' => __( 'Input Box Settings', 'woocommerce-product-addon' ), + 'desc' => __( 'PPOM frontend elements can be styled from these settings.', 'woocommerce-product-addon' ), + ), + 'ppom_input_box_bgclr' => array( + 'type' => 'color', + 'title' => __( 'Background Color', 'woocommerce-product-addon' ), + 'output' => array( 'background-color' => '.ppom-wrapper input, .ppom-wrapper select, .ppom-wrapper textarea' ), + ), + 'ppom_input_box_txtclr' => array( + 'type' => 'color', + 'title' => __( 'Text Color', 'woocommerce-product-addon' ), + 'output' => array( 'color' => '.ppom-wrapper input, .ppom-wrapper select, .ppom-wrapper textarea' ), + ), + 'ppom_input_box_border' => array( + 'type' => 'css_editor', + 'title' => __( 'Border Style', 'woocommerce-product-addon' ), + 'mode' => 'border', + 'output' => '.ppom-wrapper input, .ppom-wrapper select, .ppom-wrapper textarea', + ), + 'ppom_input_box_border_focus' => array( + 'type' => 'css_editor', + 'title' => __( 'Border Focus Style', 'woocommerce-product-addon' ), + 'mode' => 'border', + 'output' => '.ppom-wrapper input:focus, .ppom-wrapper select:focus, .ppom-wrapper textarea:focus', + ), + 'ppom_input_box_border_shadow_focus' => array( + 'type' => 'text', + 'title' => __( 'Box Shodow Focus', 'woocommerce-product-addon' ), + 'desc' => __( 'If you don\'t want to apply it, simply set the value to \'none.\'', 'woocommerce-product-addon' ), + 'hint' => '0 0 0 0.2rem rgb(0 123 255 / 25%)', + 'reference' => array( + 'ref_title' => __( 'See reference', 'woocommerce-product-addon' ), + 'ref_link' => 'https://www.w3schools.com/cssref/css3_pr_box-shadow.asp', + ), + ), + 'ppom_styles_price_table_section' => array( + 'type' => 'section', + 'title' => __( 'Price Table Settings', 'woocommerce-product-addon' ), + ), + 'ppom_price_table_txtclr' => array( + 'type' => 'color', + 'title' => __( 'Text Color', 'woocommerce-product-addon' ), + 'output' => array( 'color' => '.ppom-wrapper #ppom-price-container table th, .ppom-wrapper #ppom-price-container table td' ), + ), + 'ppom_price_table_bgclr' => array( + 'type' => 'color', + 'title' => __( 'Background Color', 'woocommerce-product-addon' ), + 'output' => array( 'background-color' => '.ppom-wrapper #ppom-price-container table' ), + ), + 'ppom_styles_tooltip_section' => array( + 'type' => 'section', + 'title' => __( 'Tooltip Settings', 'woocommerce-product-addon' ), + ), + 'ppom_input_tooltip_iconclr' => array( + 'type' => 'color', + 'title' => __( 'Icon Color', 'woocommerce-product-addon' ), + 'output' => array( 'color' => '.ppom-wrapper .ppom-tooltip ' ), + ), + 'ppom_input_tooltip_maxwidth' => array( + 'type' => 'text', + 'title' => __( 'Max. Width', 'woocommerce-product-addon' ), + 'desc' => __( 'Default: 500px', 'woocommerce-product-addon' ), + ), + 'ppom_input_tooltip_txtclr' => array( + 'type' => 'color', + 'title' => __( 'Text Color', 'woocommerce-product-addon' ), + ), + 'ppom_input_tooltip_bgclr' => array( + 'type' => 'color', + 'title' => __( 'Background Color', 'woocommerce-product-addon' ), + ), + 'ppom_input_tooltip_borderclr' => array( + 'type' => 'color', + 'title' => __( 'Border Color', 'woocommerce-product-addon' ), + ), + 'ppom_input_tooltip_position' => array( + 'type' => 'select', + 'title' => __( 'Position', 'woocommerce-product-addon' ), + 'options' => array( + 'top' => __( 'Top', 'woocommerce-product-addon' ), + 'bottom' => __( 'Bottom', 'woocommerce-product-addon' ), + 'left' => __( 'Left', 'woocommerce-product-addon' ), + 'right' => __( 'Right', 'woocommerce-product-addon' ), + ), + ), + 'ppom_input_tooltip_animation' => array( + 'type' => 'select', + 'title' => __( 'Animation', 'woocommerce-product-addon' ), + 'options' => array( + 'fade' => __( 'Fade', 'woocommerce-product-addon' ), + 'grow' => __( 'Grow', 'woocommerce-product-addon' ), + 'swing' => __( 'Swing', 'woocommerce-product-addon' ), + 'slide' => __( 'Slide', 'woocommerce-product-addon' ), + 'fall' => __( 'Fall', 'woocommerce-product-addon' ), + ), + ), + 'ppom_input_tooltip_interactive' => array( + 'type' => 'checkbox', + 'title' => __( 'Interactive', 'woocommerce-product-addon' ), + 'desc' => __( 'Allow users to interact with the tooltip.', 'woocommerce-product-addon' ), + ), + 'ppom_input_tooltip_trigger' => array( + 'type' => 'checkbox', + 'title' => __( 'Open Tooltip on click', 'woocommerce-product-addon' ), + 'desc' => __( 'Allow users to open the tooltip by clicking on it. Default behavior is hover.', 'woocommerce-product-addon' ), + ), + ); + + $panels = array( + 'ppom_admin_pro_settings' => array( + 'id' => 'ppom_admin_pro_settings', + 'title' => __( 'Pro Settings', 'woocommerce-product-addon' ), + 'desc' => '', + 'is_available' => false, + 'is_sabpanel' => true, + ), + 'ppom_admin_fields_settings' => array( + 'id' => 'ppom_admin_fields_settings', + 'title' => __( 'Fields Settings', 'woocommerce-product-addon' ), + 'is_available' => false, + 'desc' => '', + 'is_sabpanel' => true, + ), + 'ppom_admin_style_settings' => array( + 'id' => 'ppom_admin_style_settings', + 'title' => __( 'Style Settings', 'woocommerce-product-addon' ), + 'desc' => '', + 'is_available' => false, + 'is_sabpanel' => true, + ), + ); + PPOMSETTINGS()->register_panel( 'ppom_general_tab', $panels ); + + + PPOMSETTINGS()->register_setting( 'ppom_admin_pro_settings', $pro_settings ); + PPOMSETTINGS()->register_setting( 'ppom_admin_style_settings', $style_settings ); + + $settings = array( + 'ppom_cart_enabled' => array( + 'type' => 'checkbox', + 'title' => __( 'Enable PPOM Cart Edit', 'woocommerce-product-addon' ), + 'desc' => __( 'Enable this option to allow editing of PPOM fields in the cart.', 'woocommerce-product-addon' ), + ), + 'ppom-cart-edit-popup' => array( + 'type' => 'checkbox', + 'title' => __( 'Popup Edit', 'woocommerce-product-addon' ), + 'desc' => __( 'Enable this option to open field editing for PPOM options in a popup.', 'woocommerce-product-addon' ), + ), + 'ppom_editcart_editoptions_text' => array( + 'type' => 'text', + 'title' => __( 'Edit Options Text', 'woocommerce-product-addon' ), + 'default' => __( 'Edit Options', 'woocommerce-product-addon' ), + 'desc' => __( 'Change the label for the edit options button.', 'woocommerce-product-addon' ), + ), + 'ppom_edit_link_class' => array( + 'type' => 'text', + 'title' => __( 'Edit Button Class', 'woocommerce-product-addon' ), + 'desc' => __( 'Add custom CSS classes to the edit button, separated by spaces.', 'woocommerce-product-addon' ), + ), + 'ppom_editcart_popup' => array( + 'type' => 'checkbox', + 'title' => __( 'Fields Modal', 'woocommerce-product-addon' ), + 'desc' => __( 'This will display PPOM fields inside a modal instead of on the cart line item, keeping your cart page simple and clean.', 'woocommerce-product-addon' ), + ), + 'ppom_editcart_popup_label' => array( + 'type' => 'text', + 'title' => __( 'Model Button Label', 'woocommerce-product-addon' ), + 'desc' => __( 'Change the label for the modal button.', 'woocommerce-product-addon' ), + ), + ); + + $panels = array( + 'ppom_addon_cartedit' => array( + 'id' => 'ppom_addon_cartedit', + 'title' => __( 'Cart Edit', 'woocommerce-product-addon' ), + 'desc' => '', + 'icon' => '', + 'is_available' => false, + 'is_sabpanel' => true, + 'active' => 'yes', + ), + ); + + PPOMSETTINGS()->register_panel( 'ppom_general_tab', $panels )->register_setting( 'ppom_addon_cartedit', $settings ); + + $settings = array( + 'ppom-enf-emails-list' => array( + 'type' => 'text', + 'title' => __( 'Emails Recepients', 'woocommerce-product-addon' ), + 'desc' => __( 'Enter the email addresses of the enquiry form recipients, separated by commas.', 'woocommerce-product-addon' ), + ), + 'ppom-enf-note' => array( + 'type' => 'textarea', + 'title' => __( 'Note', 'woocommerce-product-addon' ), + 'desc' => __( 'Set the message to be displayed on the enquiry form.', 'woocommerce-product-addon' ), + 'default' => 'All selected data will be sent to vendor', + ), + 'ppom-enf-send-msg' => array( + 'type' => 'textarea', + 'title' => __( 'Send Message', 'woocommerce-product-addon' ), + 'desc' => __( 'Set the message to be displayed after the enquiry form is submitted.', 'woocommerce-product-addon' ), + ), + 'ppom-enf-btn-title' => array( + 'type' => 'text', + 'title' => __( 'Button Title', 'woocommerce-product-addon' ), + 'desc' => __( 'Change the title of the enquiry form button.', 'woocommerce-product-addon' ), + ), + 'ppom-enf-btn-class' => array( + 'type' => 'text', + 'title' => __( 'Button Class', 'woocommerce-product-addon' ), + 'desc' => __( ' Add custom CSS classes to the enquiry form button, separated by commas.', 'woocommerce-product-addon' ), + ), + 'ppom-enf-btn-text-color' => array( + 'type' => 'color', + 'title' => __( 'Button Text Color', 'woocommerce-product-addon' ), + ), + 'ppom-enf-btn-bg-color' => array( + 'type' => 'color', + 'title' => __( 'Button Background Color', 'woocommerce-product-addon' ), + ), + 'ppom-enf-user-send' => array( + 'type' => 'checkbox', + 'title' => __( 'Send Enquiry Form Data to User', 'woocommerce-product-addon' ), + 'desc' => __( 'Enable this option to send a copy of the enquiry form data to the user.', 'woocommerce-product-addon' ), + ), + 'ppom-enf-hide-cart' => array( + 'type' => 'checkbox', + 'title' => __( 'Hide Add to Cart Button', 'woocommerce-product-addon' ), + 'desc' => __( 'Enable this option to hide the \'Add to Cart\' button on the product page.', 'woocommerce-product-addon' ), + ), + ); + + $panels = array( + 'ppom_addon_enquiryform' => array( + 'id' => 'ppom_addon_enquiryform', + 'title' => __( 'Enquiry Form', 'woocommerce-product-addon' ), + 'desc' => '', + 'icon' => '', + 'is_available' => false, + 'active' => 'yes', + 'is_sabpanel' => true, + ), + ); + + + PPOMSETTINGS()->register_panel( 'ppom_general_tab', $panels )->register_setting( 'ppom_addon_enquiryform', $settings ); + + + $settings = array( + 'ppom_fieldspopup_section' => array( + 'type' => 'section', + 'is_available' => false, + 'title' => __( 'Fields Popup', 'woocommerce-product-addon' ), + ), + 'ppom-fieldspopup-enable' => array( + 'type' => 'checkbox', + 'is_available' => false, + 'title' => __( 'Enable Fields Popup', 'woocommerce-product-addon' ), + 'desc' => __( 'Enable the PPOM fields popup for all products.', 'woocommerce-product-addon' ), + ), + 'ppom-fieldspopup-btn-label' => array( + 'type' => 'text', + 'is_available' => false, + 'title' => __( 'Button Label', 'woocommerce-product-addon' ), + 'desc' => __( 'Set the label for the popup button.', 'woocommerce-product-addon' ), + ), + 'ppom-fieldspopup-btn-textcolor' => array( + 'type' => 'color', + 'is_available' => false, + 'title' => __( 'Button Text Color', 'woocommerce-product-addon' ), + ), + 'ppom-fieldspopup-btn-bgcolor' => array( + 'type' => 'color', + 'is_available' => false, + 'title' => __( 'Button Background Color', 'woocommerce-product-addon' ), + ), + ); + + PPOMSETTINGS()->register_setting( 'ppom_admin_fields_settings', $settings ); + + $settings = array( + 'ppom_collapse_section' => array( + 'type' => 'section', + 'is_available' => false, + 'title' => __( 'Collapse Field', 'woocommerce-product-addon' ), + ), + 'ppom-colapse-multiple-open' => array( + 'type' => 'checkbox', + 'is_available' => false, + 'title' => __( 'Multiple Collapse Open', 'woocommerce-product-addon' ), + 'desc' => __( 'Allow multiple collapsible sections to be open at the same time.', 'woocommerce-product-addon' ), + ), + 'ppom-colapse-hide-arrow' => array( + 'type' => 'checkbox', + 'is_available' => false, + 'title' => __( 'Hide Headline Arrow', 'woocommerce-product-addon' ), + 'desc' => __( 'Hide the arrow displayed under the headline.', 'woocommerce-product-addon' ), + ), + 'ppom-colapse-icon-position' => array( + 'type' => 'select', + 'is_available' => false, + 'title' => __( 'Collapse Icon Position', 'woocommerce-product-addon' ), + 'default' => 'right', + 'options' => array( + 'left' => 'Left', + 'right' => 'Right', + ), + 'desc' => __( 'Control the position of the collapse icon.', 'woocommerce-product-addon' ), + ), + 'ppom-colapse-text-color' => array( + 'type' => 'color', + 'is_available' => false, + 'title' => __( 'Collapse Text Color', 'woocommerce-product-addon' ), + ), + 'ppom-colapse-bg-color' => array( + 'type' => 'color', + 'is_available' => false, + 'title' => __( 'Collapse Background Color', 'woocommerce-product-addon' ), + ), + 'ppom-colapse-open-text-color' => array( + 'type' => 'color', + 'is_available' => false, + 'title' => __( 'Collapse Open Text Color', 'woocommerce-product-addon' ), + ), + 'ppom-colapse-open-bg-color' => array( + 'type' => 'color', + 'is_available' => false, + 'title' => __( 'Collapse Open Background Color', 'woocommerce-product-addon' ), + ), + 'ppom-collapse-nextprev' => array( + 'type' => 'checkbox', + 'is_available' => false, + 'title' => __( 'Allow Next/Prev', 'woocommerce-product-addon' ), + 'desc' => __( 'Allow user to show/hide collapse using prev/next button.', 'woocommerce-product-addon' ), + ), + ); + + PPOMSETTINGS()->register_setting( 'ppom_admin_fields_settings', $settings ); + + + $settings = array( + 'ppom_repeater_section' => array( + 'type' => 'section', + 'is_available' => false, + 'title' => __( 'Field Repeater', 'woocommerce-product-addon' ), + ), + 'ppom_repeater_clone_title' => array( + 'type' => 'text', + 'is_available' => false, + 'title' => __( 'Clone Title', 'woocommerce-product-addon' ), + 'desc' => __( 'Set the title attribute for the Clone icon.', 'woocommerce-product-addon' ), + ), + 'ppom_repeater_remove_title' => array( + 'type' => 'text', + 'is_available' => false, + 'title' => __( 'Remove Title', 'woocommerce-product-addon' ), + 'desc' => __( 'Set the title attribute for the Remove icon.', 'woocommerce-product-addon' ), + ), + 'ppom_repeater_icons_size' => array( + 'type' => 'text', + 'is_available' => false, + 'title' => __( 'Icons Size', 'woocommerce-product-addon' ), + 'desc' => __( 'Icons size e.g 25px. Defaults to 20px.', 'woocommerce-product-addon' ), + ), + 'ppom_repeater_clone_mode' => array( + 'type' => 'select', + 'is_available' => false, + 'options' => [ + 'first_box' => 'Clone from first box only', + 'each_box' => 'Clone from each box', + ], + 'title' => __( 'Clone Mode', 'woocommerce-product-addon' ), + 'desc' => __( 'How to clone the fields', 'woocommerce-product-addon' ), + ), + 'ppom_repeater_clone_position' => array( + 'type' => 'select', + 'is_available' => false, + 'options' => [ + 'top' => 'Top', + 'bottom' => 'Bottom', + ], + 'title' => __( 'Clone Icons Position', 'woocommerce-product-addon' ), + 'desc' => __( 'Set the placement of the clone icons within the repeater fields.', 'woocommerce-product-addon' ), + ), + 'ppom_repeater_icon_lib' => array( + 'type' => 'select', + 'is_available' => false, + 'options' => [ + 'dashicons' => 'Dashicons', + 'fontawesome' => 'FontAwesome', + ], + 'title' => __( 'Icons Library', 'woocommerce-product-addon' ), + 'desc' => __( 'Select the icon library to be used for displaying icons.', 'woocommerce-product-addon' ), + ), + ); + + PPOMSETTINGS()->register_setting( 'ppom_admin_fields_settings', $settings ); + + + $settings = array( + 'ppom_bq_section' => array( + 'type' => 'section', + 'is_available' => false, + 'title' => __( 'Bulk Quantity', 'woocommerce-product-addon' ), + ), + 'ppom-bq-display-type' => array( + 'type' => 'select', + 'is_available' => false, + 'title' => __( 'Display Type', 'woocommerce-product-addon' ), + 'default' => 'Bulk Quantity Standard', + 'options' => array( + 'bq_standard' => __( 'Bulk Quantity Standard', 'woocommerce-product-addon' ), + 'bq_packaged' => __( 'Bulk Quantity Packaged', 'woocommerce-product-addon' ) + ), + 'desc' => __( 'Choose how bulk quantities are displayed. Select \'Bulk Quantity Standard\' for standard bulk orders or \'Bulk Quantity Packaged\' for pre-packaged bulk quantities.', 'woocommerce-product-addon' ), + ) + ); + + PPOMSETTINGS()->register_setting( 'ppom_admin_fields_settings', $settings ); + + $integration_settings = array(); + + $integration_settings['ppom_integrations_rest'] = array( + 'type' => 'section', + 'title' => __( 'REST API', 'woocommerce-product-addon' ), + ); + $integration_settings['ppom_api_enable'] = array( + 'type' => 'checkbox', + 'title' => __( 'PPOM REST API', 'woocommerce-product-addon' ), + 'desc' => __( 'Check this option to enable PPOM REST API.', 'woocommerce-product-addon' ), + ); + $integration_settings['ppom_rest_secret_key'] = array( + 'type' => 'text', + 'title' => __( 'Secret Key', 'woocommerce-product-addon' ), + 'desc' => __( 'Enter any characters to create a secret key. This key must be provided when making API requests.', 'woocommerce-product-addon' ), + ); + + $integration_settings['ppom_integrations_wcfm'] = array( + 'type' => 'section', + 'title' => __( 'WCFM Vendors', 'woocommerce-product-addon' ), + ); + $integration_settings['ppom_wcfm_allow_vendors'] = array( + 'type' => 'checkbox', + 'title' => __( 'Allow Vendors to Create/Edit PPOM Fields', 'woocommerce-product-addon' ), + 'desc' => __( 'Enable this option to allow vendors to create or edit PPOM fields. These fields will be global.', 'woocommerce-product-addon' ), + 'label' => __( 'Yes', 'woocommerce-product-addon' ), + ); + $integration_settings['ppom_label_wcfm'] = array( + 'type' => 'text', + 'title' => __( 'Store Title', 'woocommerce-product-addon' ), + 'desc' => __( 'Set the label to display on the product edit page.', 'woocommerce-product-addon' ), + 'default' => __( 'Custom Fields', 'woocommerce-product-addon' ), + // Uncomment this section if you want to add conditions + // 'conditions' => array( + // array('ppom_wcfm_allow_vendors' , '==', array('true')), + // ) + ); + + + $panels = array( + 'ppom_integrations' => array( + 'id' => 'ppom_integrations', + 'is_available' => false, + 'title' => __( 'Integrations', 'woocommerce-product-addon' ), + 'is_sabpanel' => true, + ) + ); + PPOMSETTINGS()->register_panel( 'ppom_general_tab', $panels )->register_setting( 'ppom_integrations', $integration_settings ); + +} +add_action('init', 'ppom_load_pro_options', 99); \ No newline at end of file diff --git a/backend/settings-panel.class.php b/backend/settings-panel.class.php index 3bce2429..f514977a 100644 --- a/backend/settings-panel.class.php +++ b/backend/settings-panel.class.php @@ -204,6 +204,7 @@ public function register_tabs( $tabs ) { public function register_panel( $tab_id, $panels ) { + $panels = apply_filters( 'ppom_register_panel', $panels ); // only used for store all Panels on single array $this->panels = array_merge( $this->panels, $panels ); @@ -219,6 +220,7 @@ public function register_panel( $tab_id, $panels ) { */ public function register_setting( $panel_id, $settings ) { + $settings = apply_filters( 'ppom_register_settings', $settings ); // only used for store all settings on single array $this->settings_array = array_merge( $this->settings_array, $settings ); @@ -312,7 +314,9 @@ function save_settings() { $response = array(); if ( isset( $_REQUEST[ self::$save_key ] ) ) { - + $_REQUEST[ self::$save_key ] = array_filter( $_REQUEST[ self::$save_key ] , function ( $key ) { + return strpos( $key, '_locked' ) === false; + }, ARRAY_FILTER_USE_KEY ); // $settings_meta = $_REQUEST[self::$save_key]; $settings_meta = array_map( function ( $setting ) { @@ -324,7 +328,6 @@ function ( $setting ) { $_REQUEST[ self::$save_key ] ); - // Generate and saved css $this->generate_css( $settings_meta ); diff --git a/backend/templates/admin-settings.php b/backend/templates/admin-settings.php index 43ed7f9d..906b2ac1 100644 --- a/backend/templates/admin-settings.php +++ b/backend/templates/admin-settings.php @@ -46,28 +46,17 @@ - -
-
-
-

- get_config( 'name' ); ?> - get_config( 'version' ); ?> -

-
-
- - -
-
-
- +

+ + +

$tab_meta ) { $panel_meta = isset( $tab_meta['panels'] ) ? $tab_meta['panels'] : array(); @@ -85,6 +74,7 @@ class="button button-primary button-large nmsf-migrate-back-btn">" > -
+ class="nmsf-label "> + + + + +
+ +

+ ', esc_url( tsdk_utmify( PPOM_UPGRADE_URL, $id ) ) ), '' ); ?> +

+
+ $video_title = isset( $reference['ref_video_title'] ) ? $reference['ref_video_title'] : ''; $video_link = isset( $reference['ref_video_link'] ) ? $reference['ref_video_link'] : ''; $input_meta['input_id'] = $id; - $condition_class = ''; + $is_input_available = isset( $input_meta['is_available'] ) ? $input_meta['is_available'] : $is_available; + if ( ! $is_input_available ) { + $condition_class .= 'ppom-is-locked-field'; + $input_meta['input_id'] = '_locked' . $input_meta['input_id']; + } if ( ! empty( $conditions ) ) { - $condition_class = 'nmsf-panel-conditional-field'; + $condition_class .= 'nmsf-panel-conditional-field'; } ?> @@ -138,6 +142,12 @@ class="nmsf-label"> class="" > '; + $is_image_file = ppom_is_file_image( $file_name ); + $ppom_file_thumb_url = $is_image_file ? ppom_get_dir_url( true ) . $file_name : PPOM_URL . '/images/file.png'; + $order_html .= ''; + $order_html .= ''; } + + $order_html .= ''; $order_html .= ''; if ( $input_type == 'cropper' ) { $cropped_file_name = ppom_file_get_name( $file_name, $item->get_product_id() ); $cropped_url = ppom_get_dir_url() . 'cropped/' . $cropped_file_name; - $order_html .= ''; // Requested by Kevin, hiding downloading file button after order on thank you page // @since version 16.6 if ( is_admin() ) { - $order_html .= ''; } @@ -1620,7 +1629,7 @@ function ppom_generate_html_for_files( $file_names, $input_type, $item ) { $edit_file_name = ppom_file_get_name( $file_name, $item->get_product_id() ); $edit_url = ppom_get_dir_url() . 'edits/' . $edit_file_name; $edit_thumb_url = ppom_get_dir_url() . 'edits/thumbs/' . $file_name; - $order_html .= ''; $order_html .= '
+ +

+ ', esc_url( tsdk_utmify( PPOM_UPGRADE_URL, $id ) ) ), '' ); ?> +

+
+

@@ -202,9 +212,9 @@ class="" -

@@ -261,27 +271,17 @@ class="" - +

+ +

- - get_config( 'form_tag' ) ) { ?> From 899b8652cf748e7611e20381f0e12aab0ae4cff0 Mon Sep 17 00:00:00 2001 From: Soare Robert Daniel Date: Mon, 16 Sep 2024 14:28:39 +0300 Subject: [PATCH 29/31] refactor: transform Download File link into a button (#343) Add the necessary functionality as a separated script. --- classes/admin.class.php | 14 +++++++++++--- inc/functions.php | 29 +++++++++++++++++++---------- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/classes/admin.class.php b/classes/admin.class.php index 4463e8f5..7083ddd9 100644 --- a/classes/admin.class.php +++ b/classes/admin.class.php @@ -84,7 +84,6 @@ function __construct() { 2, 10 ); - } /** @@ -388,6 +387,17 @@ function ppom_tabs_custom_style() { th.column-ppom_meta { width: 10% !important; } + + /* PPOM File Upload uploaded files display */ + td.ppom-files-display { + display: flex; + flex-direction: column; + gap: 3px; + } + + td.ppom-files-display a.button { + text-align: center; + } init(); } - - } diff --git a/inc/functions.php b/inc/functions.php index 0d01f551..d85bd192 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -1580,36 +1580,45 @@ function ppom_generate_html_for_files( $file_names, $input_type, $item ) { foreach ( $file_name_array as $file_name ) { $file_edit_path = ppom_get_dir_path( 'edits' ) . ppom_file_get_name( $file_name, $item->get_product_id() ); - // Making file thumb download with new path $ppom_file_url = ppom_get_file_download_url( $file_name, $item->get_order_id(), $item->get_product_id() ); - $ppom_file_thumb_url = ppom_is_file_image( $file_name ) ? ppom_get_dir_url( true ) . $file_name : PPOM_URL . '/images/file.png'; - $order_html .= '
'; - $order_html .= ''; - $order_html .= '
'; + if ( $is_image_file ) { + $order_html .= ''; + } + + $order_html .= ''; + + if ( $is_image_file ) { + $order_html .= ''; + } // Requested by Kevin, hiding downloading file button after order on thank you page // @since version 16.6 if ( is_admin() ) { - $order_html .= ''; + $order_html .= ''; $order_html .= __( 'Download File', 'woocommerce-product-addon' ); - $order_html .= '
'; + $order_html .= '
'; $order_html .= ''; $order_html .= ''; + $order_html .= ''; $order_html .= __( 'Cropped', 'woocommerce-product-addon' ); $order_html .= '
'; + $order_html .= '
'; $order_html .= ''; $order_html .= ''; From 83145d00f7efb11138de5b1c71f7cfbd69ad39f1 Mon Sep 17 00:00:00 2001 From: Soare Robert Daniel Date: Tue, 17 Sep 2024 13:43:58 +0300 Subject: [PATCH 30/31] fix: delete non-img file btn and workflow (#345) --- inc/files.php | 23 ++++++---- js/file-upload.js | 113 ++++++++++++++++++++++++++++++++-------------- 2 files changed, 94 insertions(+), 42 deletions(-) diff --git a/inc/files.php b/inc/files.php index 484559ba..db7a67ab 100644 --- a/inc/files.php +++ b/inc/files.php @@ -345,17 +345,20 @@ function ppom_upload_file() { // Deleting file function ppom_delete_file() { - $file_name = sanitize_file_name( $_REQUEST ['file_name'] ); + if ( ! isset( $_REQUEST ['file_name'] ) || ! isset( $_REQUEST['ppom_nonce'] ) ) { + echo __( 'Missing data.', 'woocommerce-product-addon' ); + die( 0 ); + } - $ppom_nonce = $_REQUEST['ppom_nonce']; + $file_name = sanitize_file_name( $_REQUEST ['file_name'] ); + $ppom_nonce = sanitize_key( $_REQUEST['ppom_nonce'] ); $file_nonce_action = 'ppom_deleting_file_action'; if ( ! wp_verify_nonce( $ppom_nonce, $file_nonce_action ) ) { - printf( __( 'Error while deleting file %s', 'woocommerce-product-addon' ), $file_name ); + printf( __( 'Verification failed for file: %s', 'woocommerce-product-addon' ), $file_name ); die( 0 ); } - $dir_path = ppom_get_dir_path(); - + $dir_path = ppom_get_dir_path(); $file_path = $dir_path . $file_name; if ( file_exists( $file_path ) && unlink( $file_path ) ) { @@ -379,7 +382,7 @@ function ppom_delete_file() { printf( __( 'Error while deleting file %s', 'woocommerce-product-addon' ), $file_path ); } } else { - printf( __( 'Error while deleting file %s', 'woocommerce-product-addon' ), $file_path ); + printf( __( 'The file %s does not exists.', 'woocommerce-product-addon' ), $file_path ); } die( 0 ); @@ -477,7 +480,7 @@ function ppom_uploaded_file_preview( $file_name, $settings ) { // Tools group $file_tools .= '
'; // $file_tools .= ''; - $file_tools .= '' . __( 'Delete', 'woocommerce-product-addon' ) . ''; + $file_tools .= ''; if ( apply_filters( 'ppom_show_image_popup', false ) ) { $file_tools .= ''; @@ -491,8 +494,10 @@ function ppom_uploaded_file_preview( $file_name, $settings ) { $file_meta .= __( 'Size: ', 'woocommerce-product-addon' ) . ppom_get_filesize_in_kb( $file_name ); $thumb_url = PPOM_URL . '/images/file.png'; - $file_tools .= ''; // delete icon - // $file_tools .= 'Delete'; //delete icon + // Tools group + $file_tools .= '
'; + $file_tools .= ''; + $file_tools .= '
'; } diff --git a/js/file-upload.js b/js/file-upload.js index ca61b54d..cab37a0d 100644 --- a/js/file-upload.js +++ b/js/file-upload.js @@ -90,53 +90,100 @@ jQuery(function($) { }); // Deleting File - $(".ppom-wrapper").on('click', '.u_i_c_tools_del', function(e) { + document.querySelector('.ppom-wrapper')?.addEventListener('click', async function(e) { + if ( + ! e.target.classList.contains('u_i_c_tools_del') || + ! plupload_instances + ) { + return; + } + e.preventDefault(); - var del_message = ppom_file_vars.delete_file_msg; - var a = confirm(del_message); - if (a) { - // it is removing from uploader instance - var fileid = $(this).closest('.ppom-file-wrapper').attr("data-fileid"); - var file_data_name = $(this).closest('div.ppom-field-wrapper').attr("data-data_name"); - // console.log(fileid); - field_file_count[file_data_name] = 0; + const delMessage = ppom_file_vars.delete_file_msg; + if ( ! confirm( delMessage ) ) return; + + const ppomFileWrapper = e.target.closest('.ppom-file-wrapper'); + const fileId = ppomFileWrapper?.getAttribute("data-fileid"); + const ppomFieldWrapper = e.target.closest('div.ppom-field-wrapper'); + const fileDataName = ppomFieldWrapper?.getAttribute("data-data_name"); - plupload_instances[file_data_name].removeFile(fileid); + if ( !fileId || !fileDataName ) return; - var filename = $('input:checkbox[name="ppom[fields][' + file_data_name + '][' + fileid + '][org]"]').val(); + field_file_count[fileDataName] = 0; - // it is removing physically if uploaded - $("#u_i_c_" + fileid).find('img').attr('src', ppom_file_vars.plugin_url + '/images/loading.gif'); + const uploaderInstance = plupload_instances[fileDataName]; + if ( uploaderInstance ) { + uploaderInstance.removeFile(fileId); + } - // console.log('filename ppom[fields][['+fileid+']'); - var data = { action: 'ppom_delete_file', file_name: filename, 'ppom_nonce': ppom_file_vars.ppom_file_delete_nonce }; + const checkbox = document.querySelector(`input[name="ppom[fields][${fileDataName}][${fileId}][org]"]`); + const fileName = checkbox?.value; - $.post(ppom_file_vars.ajaxurl, data, function(resp) { - alert(resp); - $("#u_i_c_" + fileid).hide(500).remove(); + if ( ! fileName ) return; - // it is removing for input Holder - $('input:checkbox[name="ppom[fields][' + file_data_name + '][' + fileid + '][org]"]').remove(); + // Delete animation. + const imageElement = document.querySelector(`#u_i_c_${fileId} img`); + if ( imageElement ) { + imageElement.src = `${ppom_file_vars.plugin_url}/images/loading.gif`; + } - // Removing file container - $(this).closest('.u_i_c_box').remove(); + const data = new URLSearchParams({ + action: 'ppom_delete_file', + file_name: fileName, + ppom_nonce: ppom_file_vars.ppom_file_delete_nonce + }); - // Removing cropper dom - if ($(".ppom-croppie-preview-" + fileid).length > 0) { - $(".ppom-croppie-preview-" + fileid).remove(); + try { + const response = await fetch(ppom_file_vars.ajaxurl, { + method: 'POST', + body: data, + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + 'X-Requested-With': 'XMLHttpRequest' } + }); - // Trigger - $.event.trigger({ - type: "ppom_uploaded_file_removed", - field_name: file_data_name, - fileid: fileid, + const responseText = await response.text(); + if ( ! response.ok ) { + confirm(`Error: ${responseText}`); + return; + } + + // Update UI + const fileContainer = document.querySelector(`#u_i_c_${fileId}`); + if ( fileContainer ) { + fileContainer.remove(); + } + + if ( checkbox ) { + checkbox.remove(); + } + + const parentBox = e.target.closest('.u_i_c_box'); + if ( parentBox ) { + parentBox.remove(); + } + + const croppiePreview = document.querySelector(`.ppom-croppie-preview-${fileId}`); + if ( croppiePreview ) { + croppiePreview.remove(); + } + + // Send action to PPOM_Validate + document.dispatchEvent(new CustomEvent("ppom_uploaded_file_removed", { + detail: { + field_name: fileDataName, + fileid: fileId, time: new Date() - }); + } + })); - field_file_count[file_data_name] -= 1; - }); + // Decrease file count + field_file_count[fileDataName] -= 1; + + } catch (error) { + confirm(`Error: ${error.message}`); } }); From ca0264eec3307c0309c06eb7d90da55cb3619147 Mon Sep 17 00:00:00 2001 From: Soare Robert Daniel Date: Fri, 20 Sep 2024 09:41:27 +0300 Subject: [PATCH 31/31] refactor: product metabox for fields attach (#382) --- classes/admin.class.php | 42 +++++++++++++ inc/admin.php | 128 +++++++++++++++++++++++++++++----------- 2 files changed, 137 insertions(+), 33 deletions(-) diff --git a/classes/admin.class.php b/classes/admin.class.php index 7083ddd9..9a4c8b25 100644 --- a/classes/admin.class.php +++ b/classes/admin.class.php @@ -398,6 +398,48 @@ function ppom_tabs_custom_style() { td.ppom-files-display a.button { text-align: center; } + + .ppom-settings-container { + display: flex; + flex-direction: column; + gap: 15px; + margin: 10px 15px; + } + + .ppom-settings-container-item { + display: flex; + align-items: center; + gap: 10px; + } + + label.ppom-settings-container-item { + width: 100%; + max-width: 600px; + margin: unset; + } + + .ppom-settings-container .ppom-upsell-link { + display: inline-flex; + align-items: center; + padding: 0.5rem 1rem; + font-size: 0.875rem; + font-weight: 500; + color: #2563eb; + background-color: #eff6ff; + border: 1px solid #bfdbfe; + border-radius: 0.375rem; + text-decoration: none; + transition: all 150ms ease-in-out; + } + + .ppom-settings-container .ppom-upsell-link:hover { + background-color: #dbeafe; + color: #1d4ed8; + } + + .ppom-settings-container .ppom-disabled-text { + color: #8d8d8d; + } ID ); $all_meta = PPOM()->get_product_meta_all(); $ppom_setting = admin_url( 'admin.php?page=ppom' ); + + $html = '
'; + + // UP-SELL + $html .= ''; + $html .= ' '; + $html .= __( 'Using multiple PPOM Fields on the same product is available in PRO.', 'woocommerce-product-addon' ); + $html .= ''; + + // PPOM Fields select table. + $html .= ''; + + $html .= '
'; + $html .= ''; + $html .= '' . __( 'Create New Meta', 'woocommerce-product-addon' ) . ''; + $html .= '
'; - $html = '
'; - $html .= '

' . __( 'Select Meta to Show Fields on this product', 'woocommerce-product-addon' ); - // $html .= __(' Or Create New Meta', 'woocommerce-product-addon'); - $html .= '

'; - - $html .= '

'; - $html .= '

'; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + $html .= ''; + foreach ( $all_meta as $meta ) { + $html .= ''; + + // Select/Checkbox + $html .= ''; - $html .= ''; - } - $html .= ''; + // ID Column + $html .= ''; - if ( $ppom->single_meta_id != 'None' ) { + // Meta Name Column + $html .= ''; - $ppom_add_args = array( - 'productmeta_id' => $ppom->single_meta_id, - 'do_meta' => 'edit', - 'product_id' => $post->ID, + // Edit Meta Shortcut Column + $url_edit = add_query_arg( + array( + 'productmeta_id' => $meta->productmeta_id, + 'do_meta' => 'edit', + ), + $ppom_setting ); - $url_edit = add_query_arg( $ppom_add_args, $ppom_setting ); - $html .= ' '; - } + $html .= ''; - // $html .= '
'; - // $html .= ' Create New Meta'; + $html .= ''; + } - $html .= '

'; + $html .= '
' . __( 'Select Meta', 'woocommerce-product-addon' ) . '' . __( 'Meta ID', 'woocommerce-product-addon' ) . '' . __( 'Meta Name', 'woocommerce-product-addon' ) . '' . __( 'Edit', 'woocommerce-product-addon' ) . '
'; + $html .= 'meta_id ) && + ( + ( + is_array( $ppom->meta_id ) && + in_array( $meta->productmeta_id, $ppom->meta_id ) + ) || + ( + is_numeric( $ppom->meta_id ) && + $ppom->meta_id === $meta->productmeta_id + ) + ) + ) { + $html .= ' checked '; + } + $html .= 'id="ppom-' . esc_attr( $meta->productmeta_id ) . '">'; + $html .= '' . $meta->productmeta_id . '' . stripslashes( $meta->productmeta_name ) . ''; + $html .= ''; + $html .= '
'; $html .= '
'; - $ppom_add_args = array( - 'action' => 'new', - 'product_id' => $post->ID, - ); - $ppom_setting_url = add_query_arg( $ppom_add_args, $ppom_setting ); + $html .= '
'; + $html .= '
'; + $html .= '' . __( 'PPOM PopUp Settings', 'woocommerce-product-addon' ) . ' (' . __( 'PRO', 'woocommerce-product-addon' ) . ')' . ''; + $html .= ''; + $html .= ''; + $html .= '
'; + + $html .= '
'; + $html .= '
'; + $html .= '' . __( 'PPOM Enquiry Form Settings', 'woocommerce-product-addon' ) . ' (' . __( 'PRO', 'woocommerce-product-addon' ) . ')' . ''; + $html .= ''; + $html .= '
'; + + ?> + +