Plugin Directory

Changeset 3469202


Ignore:
Timestamp:
02/25/2026 08:51:44 AM (2 weeks ago)
Author:
triopsi
Message:

Update to version 2.0.1 from GitHub

Location:
extra-product-data-for-woocommerce
Files:
82 added
42 deleted
36 edited
1 copied

Legend:

Unmodified
Added
Removed
  • extra-product-data-for-woocommerce/tags/2.0.1/assets/css/admin-backend.css

    r3460848 r3469202  
    1 #extra-product-data{padding:10px}table.exprdawc_attribute_table td{vertical-align:middle!important}table.exprdawc_attribute_table td.exprdawc_attribute_require_checkbox label{padding-top:15px}table.exprdawc_field_table{border-collapse:collapse;width:100%}table.exprdawc_field_table th{background-color:#f1f1f1;font-weight:700;padding:10px;text-align:left}table.exprdawc_field_table tr:nth-child(2n){background-color:#f9f9f9}table.exprdawc_field_table tr.exprdawc_fields_wrapper{border-bottom:1px solid #ddd}table.exprdawc_field_table tr.exprdawc_fields_wrapper:hover{background-color:#f1f1f1}table.exprdawc_field_table tr.exprdawc_fields_wrapper:last-child{border-bottom:none}table.exprdawc_field_table td{padding:0}table.exprdawc_field_table tfoot tr{background-color:#fafafa;border:1px solid #ccc}table.exprdawc_field_table tfoot td{padding:10px;text-align:center;vertical-align:middle}table.exprdawc_field_table tfoot td.exprdawc_add_field_col{text-align:left}table.exprdawc_field_table tfoot td.exprdawc_export_col{text-align:right}table.exprdawc_field_table tfoot .button{line-height:13px;padding:5px}table.exprdawc_fields_table{border-collapse:collapse;width:100%}table.exprdawc_fields_table tr{border:0}table.exprdawc_fields_table tbody td{padding:10px;text-align:left;vertical-align:middle;white-space:nowrap;width:auto}table.exprdawc_fields_table tbody td input[type=number],table.exprdawc_fields_table tbody td input[type=text],table.exprdawc_fields_table tbody td select,table.exprdawc_fields_table tbody td textarea{border:1px solid #ccc;border-radius:4px;box-sizing:border-box;padding:5px;width:100%}table.exprdawc_fields_table tbody td select{text-overflow:ellipsis}table.exprdawc_fields_table tbody td button.add_rule,table.exprdawc_fields_table tbody td button.exprdawc_copy_custom_field,table.exprdawc_fields_table tbody td button.exprdawc_remove_custom_field,table.exprdawc_fields_table tbody td button.remove_rule{line-height:13px;padding:5px}table.exprdawc_fields_table tbody td.move i{cursor:move}table.exprdawc_fields_table tbody td.cl-arr i{cursor:pointer}table.exprdawc_settings_table{width:100%}table.exprdawc_settings_table label.exprdawc_label{align-items:center;display:flex;float:none;margin:5px 0;padding:0;text-align:left;width:auto}table.exprdawc_settings_table label.exprdawc_label .checkbox{margin-right:5px!important}table.exprdawc_settings_table td{padding:10px;vertical-align:middle}table.exprdawc_options_table{border:1px solid #ccc;border-collapse:collapse;margin-top:10px;width:100%}table.exprdawc_options_table td,table.exprdawc_options_table th{border-bottom:1px solid #ddd;padding:10px;text-align:left}table.exprdawc_options_table th{background-color:#f1f1f1}table.exprdawc_options_table tr:hover{background-color:#f9f9f9}table.exprdawc_options_table .button{background-color:#0073aa;border:none;border-radius:4px;color:#fff;cursor:pointer;padding:5px 10px}table.exprdawc_options_table .button:hover{background-color:#005a87;color:#fff}.exprdawc_attribute h3 .sort{cursor:move;float:right;font-size:15px;font-weight:400;height:26px;margin-right:.5em;text-align:center;vertical-align:middle;width:17px}.exprdawc_attribute h3 .sort:before{color:#999;content:"";display:block;float:left;font-family:Dashicons;height:100%;line-height:28px;text-align:center;width:17px}.exprdawc_attribute h3 .sort:hover:before{color:#777}.exprdawc_attribute h3:hover .sort,.exprdawc_attribute.ui-sortable-helper .sort{visibility:visible}.exprdawc_attribute.wc-metabox.postbox{border-left:0;border-right:0;border-top:0}.exprdawc_panel{display:block}.exprdawc_panel p.description{margin:0}.exprdawc_panel h2{font-size:1.5em!important;padding:0 0 10px!important}.exprdawc_panel .wc-metabox{background:#fff;border-bottom:1px solid #eee;margin:0!important}.exprdawc_panel .wc-metabox.exprdawc_attribute h3{cursor:pointer;padding:.5em .75em .5em 1em!important}.exprdawc_panel .wc-metabox.exprdawc_attribute h3 .sort,.exprdawc_panel .wc-metabox.exprdawc_attribute h3 a.delete,.exprdawc_panel .wc-metabox.exprdawc_attribute h3 a.edit{margin-top:.25em}#woocommerce-coupon-data ul.wc-tabs li.custom_fields_options a:before,#woocommerce-product-data ul.wc-tabs li.custom_fields_options a:before,.woocommerce ul.wc-tabs li.custom_fields_options a:before{content:"";font-family:Dashicons}.exprdawc_conditional_logic_table{border-collapse:collapse;margin-bottom:20px;width:100%}.exprdawc_conditional_logic_table td,.exprdawc_conditional_logic_table th{border:1px solid #ddd;padding:10px;text-align:left}.exprdawc_conditional_logic_table th{background-color:#f9f9f9;font-weight:700}.exprdawc_conditional_logic_table .exprdawc_label{display:block;font-weight:700;margin-bottom:5px}.exprdawc_conditional_logic_table .exprdawc_input{border:1px solid #ccc;border-radius:4px;box-sizing:border-box;padding:5px;width:100%}.exprdawc_conditional_logic_table .exprdawc_checkbox{width:auto}.exprdawc_conditional_logic_table .exprdawc_textarea{border:1px solid #ccc;border-radius:4px;padding:8px;width:100%}.exprdawc_conditional_logic_table .exprdawc_no_entry_message{color:#a00;font-weight:700}.exprdawc_conditional_logic_table h2{text-align:left;text-transform:uppercase}.exprdawc_conditional_logic_table .exprdawc_rule_group{background-color:#f9f9f9;border:1px solid #ddd;border-radius:4px;margin-bottom:10px;padding:10px}.exprdawc_conditional_logic_table .exprdawc_rule_group .exprdawc_rule{align-items:center;display:flex;margin-bottom:10px}.exprdawc_conditional_logic_table .exprdawc_rule_group .exprdawc_rule .exprdawc_input{margin-right:10px}.exprdawc_conditional_logic_table .exprdawc_rule_group .exprdawc_rule .button{margin-left:10px}.exprdawc_conditional_logic_table .exprdawc_rule_group .add_rule_group{margin-top:10px}.exprdawc_no_entry_message{background:#fafafa;border:1px solid #c3c4c7;border-bottom:none;color:#5b5b5b;display:block;margin:10px 0 0;padding-bottom:1em;padding-top:75px;position:relative;text-align:center}.exprdawc_no_entry_message:before{color:#6c6c6c;content:"";font-family:Dashicons;font-size:70px;left:50%;position:absolute;top:0;transform:translateX(-50%)}a.exprdawc-export,a.exprdawc-import{color:#0073aa;font-size:small;margin:0 5px;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}a.exprdawc-export:before,a.exprdawc-import:before{font-family:Dashicons;margin-right:5px;position:relative}a.exprdawc-export:hover,a.exprdawc-import:hover{color:#005a87;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}a.exprdawc-export:before{content:""}a.exprdawc-import:before{content:""}
     1#extra-product-data{padding:10px 10px}table.exprdawc_attribute_table td{vertical-align:middle !important}table.exprdawc_attribute_table td.exprdawc_attribute_require_checkbox label{padding-top:15px}table.exprdawc_field_table{width:100%;border-collapse:collapse}table.exprdawc_field_table th{background-color:#f1f1f1;font-weight:bold;padding:10px;text-align:left}table.exprdawc_field_table tr:nth-child(even){background-color:#f9f9f9}table.exprdawc_field_table tr.exprdawc_fields_wrapper{border-bottom:1px solid #ddd}table.exprdawc_field_table tr.exprdawc_fields_wrapper:hover{background-color:#f1f1f1}table.exprdawc_field_table tr.exprdawc_fields_wrapper:last-child{border-bottom:none}table.exprdawc_field_table td{padding:0px}table.exprdawc_field_table tfoot tr{background-color:#fafafa;border:1px solid #ccc}table.exprdawc_field_table tfoot td{padding:10px;text-align:center;vertical-align:middle}table.exprdawc_field_table tfoot td.exprdawc_add_field_col{text-align:left}table.exprdawc_field_table tfoot td.exprdawc_export_col{text-align:right}table.exprdawc_field_table tfoot .button{padding:5px;line-height:13px}table.exprdawc_fields_table{width:100%;border-collapse:collapse}table.exprdawc_fields_table tr{border:0px}table.exprdawc_fields_table tbody td{vertical-align:middle;padding:10px;text-align:left;width:auto;white-space:nowrap}table.exprdawc_fields_table tbody td input[type=text],table.exprdawc_fields_table tbody td input[type=number],table.exprdawc_fields_table tbody td textarea{width:100%;padding:5px;border:1px solid #ccc;border-radius:4px;box-sizing:border-box}table.exprdawc_fields_table tbody td select{width:100%;padding:5px;border:1px solid #ccc;border-radius:4px;box-sizing:border-box;text-overflow:ellipsis}table.exprdawc_fields_table tbody td button.add_rule,table.exprdawc_fields_table tbody td button.exprdawc_remove_custom_field,table.exprdawc_fields_table tbody td button.exprdawc_copy_custom_field,table.exprdawc_fields_table tbody td button.remove_rule{padding:5px;line-height:13px}table.exprdawc_fields_table tbody td.move i{cursor:move}table.exprdawc_fields_table tbody td.cl-arr i{cursor:pointer}table.exprdawc_settings_table{width:100%}table.exprdawc_settings_table label.exprdawc_label{float:none;padding:0px;margin:5px 0px;text-align:left;display:flex;width:auto;align-items:center}table.exprdawc_settings_table label.exprdawc_label .checkbox{margin-right:5px !important}table.exprdawc_settings_table td{vertical-align:middle;padding:10px}table.exprdawc_options_table{width:100%;border-collapse:collapse;margin-top:10px;border:1px solid #ccc}table.exprdawc_options_table th,table.exprdawc_options_table td{padding:10px;text-align:left;border-bottom:1px solid #ddd}table.exprdawc_options_table th{background-color:#f1f1f1}table.exprdawc_options_table tr:hover{background-color:#f9f9f9}table.exprdawc_options_table .button{padding:5px 10px;border:none;border-radius:4px;background-color:#0073aa;color:#fff;cursor:pointer}table.exprdawc_options_table .button:hover{background-color:#005a87;color:#fff}.exprdawc_attribute h3 .sort{width:17px;height:26px;cursor:move;float:right;font-size:15px;font-weight:400;margin-right:.5em;text-align:center;vertical-align:middle}.exprdawc_attribute h3 .sort::before{content:"";font-family:"Dashicons";text-align:center;line-height:28px;color:#999;display:block;width:17px;float:left;height:100%}.exprdawc_attribute h3 .sort:hover::before{color:#777}.exprdawc_attribute h3:hover .sort,.exprdawc_attribute.ui-sortable-helper .sort{visibility:visible}.exprdawc_attribute.wc-metabox.postbox{border-top:0px;border-left:0px;border-right:0px}.exprdawc_panel{display:block}.exprdawc_panel p.description{margin:0}.exprdawc_panel h2{font-size:1.5em !important;padding:0px 0px 10px 0px !important}.exprdawc_panel .wc-metabox{background:#fff;border-bottom:1px solid #eee;margin:0 !important}.exprdawc_panel .wc-metabox.exprdawc_attribute h3{cursor:pointer;padding:.5em .75em .5em 1em !important}.exprdawc_panel .wc-metabox.exprdawc_attribute h3 a.delete,.exprdawc_panel .wc-metabox.exprdawc_attribute h3 a.edit,.exprdawc_panel .wc-metabox.exprdawc_attribute h3 .sort{margin-top:.25em}#woocommerce-product-data ul.wc-tabs li.custom_fields_options a::before,#woocommerce-coupon-data ul.wc-tabs li.custom_fields_options a::before,.woocommerce ul.wc-tabs li.custom_fields_options a::before{font-family:"Dashicons";content:""}.exprdawc_conditional_logic_table{width:100%;border-collapse:collapse;margin-bottom:20px}.exprdawc_conditional_logic_table th,.exprdawc_conditional_logic_table td{padding:10px;border:1px solid #ddd;text-align:left}.exprdawc_conditional_logic_table th{background-color:#f9f9f9;font-weight:bold}.exprdawc_conditional_logic_table .exprdawc_label{display:block;margin-bottom:5px;font-weight:bold}.exprdawc_conditional_logic_table .exprdawc_input{width:100%;padding:5px;border:1px solid #ccc;border-radius:4px;box-sizing:border-box}.exprdawc_conditional_logic_table .exprdawc_checkbox{width:auto}.exprdawc_conditional_logic_table .exprdawc_textarea{width:100%;padding:8px;border:1px solid #ccc;border-radius:4px}.exprdawc_conditional_logic_table .exprdawc_no_entry_message{color:#a00;font-weight:bold}.exprdawc_conditional_logic_table h2{text-align:left;text-transform:uppercase}.exprdawc_conditional_logic_table .exprdawc_rule_group{margin-bottom:10px;padding:10px;border:1px solid #ddd;background-color:#f9f9f9;border-radius:4px}.exprdawc_conditional_logic_table .exprdawc_rule_group .exprdawc_rule{display:flex;align-items:center;margin-bottom:10px}.exprdawc_conditional_logic_table .exprdawc_rule_group .exprdawc_rule .exprdawc_input{margin-right:10px}.exprdawc_conditional_logic_table .exprdawc_rule_group .exprdawc_rule .button{margin-left:10px}.exprdawc_conditional_logic_table .exprdawc_rule_group .add_rule_group{margin-top:10px}.exprdawc_no_entry_message{padding-top:75px;margin:10px 0 0;position:relative;text-align:center;display:block;padding-bottom:1em;background:#fafafa;color:#5b5b5b;border:1px solid #c3c4c7;border-bottom:none}.exprdawc_no_entry_message::before{font-family:"Dashicons";content:"";font-size:70px;color:#6c6c6c;position:absolute;top:0px;left:50%;-ms-transform:translateX(-50%);transform:translateX(-50%)}a.exprdawc-export,a.exprdawc-import{text-decoration:underline dotted;font-size:small;color:#0073aa;margin:0 5px}a.exprdawc-export::before,a.exprdawc-import::before{font-family:"Dashicons";margin-right:5px;position:relative}a.exprdawc-export:hover,a.exprdawc-import:hover{color:#005a87;text-decoration:underline dotted}a.exprdawc-export::before{content:""}a.exprdawc-import::before{content:""}tr.exprdawc-validation-error{background-color:#fee !important;box-shadow:inset 0 0 0 1px red !important}tr.exprdawc-validation-error .exprdawc_fields_table{border:1px solid red}input.exprdawc-invalid-field{border-color:#d63638 !important;background-color:#ffe8e8 !important;box-shadow:inset 0 0 0 1px #d63638 !important}input.exprdawc-invalid-field:focus{border-color:#d63638 !important;background-color:#fff !important;box-shadow:0 0 0 3px rgba(214,54,56,.1) !important}.exprdawc-validation-error:first-of-type{animation:pulse-error .5s ease-in-out 2}@keyframes pulse-error{0%,100%{background-color:#fee}50%{background-color:#fcc}}/*# sourceMappingURL=admin-backend.css.map */
  • extra-product-data-for-woocommerce/tags/2.0.1/assets/css/forms.css

    r3213497 r3469202  
    1 .exprdawc-label{display:block;font-weight:700}.exprdawc-field-input-yes-no,.exprdawc-field-wrapper-yes-no select,.exprdawc-input-wrapper .input-text{margin:2px 0 0;max-width:none;padding:5px;vertical-align:middle;width:100%}.exprdawc-field-input-yes-no,.exprdawc-field-wrapper-yes-no select{text-overflow:ellipsis}.exprdawc-description{font-size:smaller;font-style:italic}.exprdawc-field-wrapper{margin-bottom:15px}
     1.exprdawc-label{font-weight:bold;display:block}.exprdawc-input-wrapper .input-text{width:100%;max-width:none;padding:5px;vertical-align:middle;margin:2px 0 0}.exprdawc-field-input-yes-no,.exprdawc-field-wrapper-yes-no select{width:100%;max-width:none;padding:5px;vertical-align:middle;margin:2px 0 0;text-overflow:ellipsis}.exprdawc-description{font-style:italic;font-size:smaller}.exprdawc-field-wrapper{margin-bottom:15px}/*# sourceMappingURL=forms.css.map */
  • extra-product-data-for-woocommerce/tags/2.0.1/assets/css/order-frontend.css

    r3206929 r3469202  
    1 .exprdawc-order-item-fields{background-color:#f9f9f9;border:1px solid #ddd;border-radius:4px;box-shadow:0 2px 4px rgba(0,0,0,.1);margin-top:10px;padding:15px}.exprdawc-order-item-fields .exprdawc-input{border:1px solid #ccc;border-radius:4px;box-sizing:border-box;margin-bottom:10px;padding:10px}.exprdawc-order-item-fields button{width:100%}
     1.exprdawc-order-item-fields{background-color:#f9f9f9;border:1px solid #ddd;border-radius:4px;padding:15px;margin-top:10px;box-shadow:0 2px 4px rgba(0,0,0,.1)}.exprdawc-order-item-fields .exprdawc-input{padding:10px;margin-bottom:10px;border:1px solid #ccc;border-radius:4px;box-sizing:border-box}.exprdawc-order-item-fields button{width:100%}/*# sourceMappingURL=order-frontend.css.map */
  • extra-product-data-for-woocommerce/tags/2.0.1/extra-product-data-for-woocommerce.php

    r3460992 r3469202  
    33 * Plugin Name: Extra Product Data for WooCommerce
    44 * Description: Adds customizable input fields per product in WooCommerce, allowing users to enter extra details on the frontend .
    5  * Version: 1.8.2
     5 * Version: 2.0.1
    66 * Author: Triopsi
    77 * Author URI: https:// triopsi.dev
    88 * License: GPLv2 or later
    99 * License URI: https:// www.gnu.org/licenses/gpl-2.0.html
    10  * Text Domain: extra - product - data - for - woocommerce
     10 * Text Domain: extra-product-data-for-woocommerce
    1111 * WC requires at least: 3.9
    1212 * WC tested up to: 9.4
    1313 * Requires Plugins: woocommerce
     14 * Requires PHP: 8.0
     15 * Requires at least: 6.0
    1416 *
    1517 * @package ExtraProductDataForWooCommerce
    1618 */
    17 
    18 use function Triopsi\Exprdawc\tr_is_woocommerce_active;
    19 use Triopsi\Exprdawc\Exprdawc_Main;
    2019
    2120if ( ! defined( 'ABSPATH' ) ) {
     
    2322}
    2423
     24use Automattic\WooCommerce\Utilities\FeaturesUtil;
     25use Triopsi\Exprdawc\Exprdawc_Main;
     26
     27// Load Composer autoloader when available.
     28$autoload_path = __DIR__ . '/vendor/autoload.php';
     29if ( file_exists( $autoload_path ) ) {
     30    require_once $autoload_path;
     31}
     32
    2533// Include constants.
    2634require_once __DIR__ . '/src/constants.php';
    2735
    28 // Include functions/helpers.
    29 require_once EXPRDAWC_SRC . 'functions.php';
    30 
    31 // Include Base Order Class.
    32 require_once EXPRDAWC_CLASSES . 'class-exprdawc-base-order-class.php';
    33 
    34 // Include main class.
    35 require_once EXPRDAWC_CLASSES . 'class-exprdawc-main.php';
    36 
    37 // Include Helper Class.
    38 require_once EXPRDAWC_CLASSES . 'class-exprdawc-helper.php';
    39 
    40 // Is WooCommerce active? Then not, display a notice.
    41 if ( ! tr_is_woocommerce_active() ) {
    42     add_action( 'admin_notices', 'exprdawc_admin_notice' );
    43 } else {
    44     // Initiate the main class.
    45     Exprdawc_Main::get_instance();
    46 }
     36// Initiate the main class.
     37Exprdawc_Main::get_instance();
    4738
    4839// Declare compatibility with WooCommerce HPOS.
     
    5041    'before_woocommerce_init',
    5142    function () {
    52         if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) {
    53             \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', __FILE__, true );
    54 
     43        if ( class_exists( FeaturesUtil::class ) ) {
     44            FeaturesUtil::declare_compatibility( 'custom_order_tables', __FILE__, true );
    5545        }
    5646    }
     
    6757    <?php
    6858}
     59
     60/**
     61 * Deactivate the plugin if the PHP version is below 8.0.
     62 */
     63register_activation_hook(
     64    __FILE__,
     65    function () {
     66        if ( version_compare( PHP_VERSION, '8.0.0', '<' ) ) {
     67            deactivate_plugins( plugin_basename( __FILE__ ) );
     68            wp_die(
     69                esc_html__( 'This plugin requires PHP 8.0 or higher.', 'extra-product-data-for-woocommerce' ),
     70                esc_html__( 'Plugin Activation Error', 'extra-product-data-for-woocommerce' ),
     71                array( 'back_link' => true )
     72            );
     73        }
     74    }
     75);
  • extra-product-data-for-woocommerce/tags/2.0.1/readme.txt

    r3461001 r3469202  
    55Tested up to: 6.7
    66Requires PHP: 8.2
    7 Stable tag: 1.8.2
     7Stable tag: 2.0.1
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    49492. Activate the plugin through the 'Plugins' screen in WordPress.
    50503. Go to any WooCommerce product page to see the additional input fields.
     51
     52== Development ==
     53
     54This plugin uses Composer autoloading for its PHP classes.
     55
     561. Run `composer install` in the plugin directory.
    5157
    5258== Frequently Asked Questions ==
     
    167173= 1.8.2 (13.02.2026) =
    168174* Fix: Required input name with full stops
     175
     176= 2.0.0 (25.02.2026) =
     177* various bug fixes in calculation, display, and when adding fields
     178* fixed default selection issues for select, checkbox, and radio
     179* added E2E tests with Playwright
     180* added WP ENV for development
     181* achieved >90% path coverage in PHPUnit
     182* fix for checking whether WooCommerce has already loaded
     183* stricter checks for usage of actions and filters
     184
     185= 2.0.1 (25.02.2026) =
     186* Fix and Bump Version to wg.org
  • extra-product-data-for-woocommerce/tags/2.0.1/src/assets/js/wc-meta-boxes-product.js

    r3460848 r3469202  
    4343            this.bindEvents();
    4444            this.noEntryContent();
     45            this.bindFormValidation();
    4546        }
    4647
     
    5758            $(document).on('click', '.add_option', this.addOption.bind(this));
    5859            $(document).on('click', '.remove_option', this.removeOption.bind(this));
    59             $(document).on('click', 'a.exprdawc-export', this.exportContent.bind(this));
    60             $(document).on('click', 'a.exprdawc-import', this.importContent.bind(this));
    6160            $(document).on('change', '.exprdawc_input', this.setDirty.bind(this));
    6261            $(document).on('change', '.exprdawc_autocomplete_field', this.checkAutocompleteField.bind(this));
     
    340339                                </table>
    341340
    342                                 <!-- Text Option/Settings for radio, checkboxes and slects -->
     341                                <!-- Text Option/Settings for radio, checkboxes and selects -->
    343342                                <table class="exprdawc_settings_table exprdawc_text_table" style="display:none;">
    344343                                    <tbody>
     
    423422            this.setDirty();
    424423            const $row = $(e.currentTarget).closest('tr');
     424            const $type = $(e.currentTarget).val();
    425425            const $optionsRow = $row.next('.exprdawc_options');
    426426            const $optionsTable = $optionsRow.find('.exprdawc_options_table');
    427427            const $placeholderText = $optionsRow.find('.exprdawc_placeholder');
    428428
    429             if ($(e.currentTarget).val() === 'radio' || $(e.currentTarget).val() === 'checkbox') {
     429            if ($type === 'radio' || $type === 'checkbox' || $type === 'select') {
    430430                $placeholderText.prop('disabled', true);
    431431                $optionsTable.show();
     
    628628         * @returns
    629629         */
    630         exportContent(e) {
    631             e.preventDefault();
    632             // Update all field indices
    633             this.updateFieldIndices();
    634             if (this.isDirty) {
    635                 alert(`${exprdawc_admin_meta_boxes.pleaseSaveBeforeExportMsg}`);
    636                 return;
    637             }
    638             const $exportString = $('#exprdawc_export_string');
    639             const exportContent = $exportString.val();
    640             if (!exportContent) {
    641                 alert(`${exprdawc_admin_meta_boxes.emptyExportMsg}`);
    642                 return;
    643             }
    644             navigator.clipboard.writeText(exportContent).then(function () {
    645                 alert(`${exprdawc_admin_meta_boxes.copySuccessMsg}`);
    646             }, function (err) {
    647                 console.error('Could not copy text: ', err);
    648                 alert(`${exprdawc_admin_meta_boxes.copyErrorMsg}`);
    649             });
    650         }
    651 
    652         /**
    653          * Import content.
    654          * @param {*} e
    655          * @returns
    656          */
    657         importContent(e) {
    658             e.preventDefault();
    659             const exportString = prompt(exprdawc_admin_meta_boxes.enterExportString);
    660             if (exportString) {
    661                 const sureImportQuestion = confirm(exprdawc_admin_meta_boxes.sureImportQuestion);
    662                 if (!sureImportQuestion) {
    663                     return;
    664                 }
    665                 const productId = $('#post_ID').val();
    666                 $.ajax({
    667                     url: ajaxurl,
    668                     method: 'POST',
    669                     data: {
    670                         action: 'exprdawc_import_custom_fields',
    671                         product_id: productId,
    672                         export_string: exportString,
    673                         security: exprdawc_admin_meta_boxes.edit_exprdawc_nonce
    674                     },
    675                     success: function (response) {
    676                         if (response.success) {
    677                             alert(exprdawc_admin_meta_boxes.importSuccessMsg);
    678                             location.reload();
    679                         } else {
    680                             alert(exprdawc_admin_meta_boxes.importErrorMsg);
    681                         }
    682                     },
    683                     error: function () {
    684                         alert(exprdawc_admin_meta_boxes.importErrorMsg);
    685                     },
    686                 });
    687             }
    688         }
    689 
    690630        /**
    691631         * Set dirty.
     
    1013953                    $input.find('option:last').prop('selected', true);
    1014954                }
    1015             });
     955
     956                // Remove validation error classes
     957                $input.removeClass('exprdawc-invalid-field');
     958            });
     959
     960            // Remove validation error class from the row
     961            $clone.removeClass('exprdawc-validation-error');
    1016962
    1017963            // Append the cloned row to the table
     
    10661012        }
    10671013
     1014        /**
     1015         * Bindet das Form-Validierungs-Event zur WordPress Post-Form.
     1016         * Prüft, ob alle exprdawc_attributes einen gefüllten Label haben, bevor gespeichert wird.
     1017         */
     1018        bindFormValidation() {
     1019            // Prüfe Form-Submit auf der WordPress Post-Edit-Seite
     1020            $('#post').on('submit', (e) => {
     1021                if (!this.validateFields()) {
     1022                    e.preventDefault();
     1023                    e.stopPropagation();
     1024                    return false;
     1025                }
     1026            });
     1027
     1028            // Prüfe auch auf Schnellspeicher-Button und Veröffentlichungs-Buttons
     1029            $('#publish, #save-post').on('click', (e) => {
     1030                if (!this.validateFields()) {
     1031                    e.preventDefault();
     1032                    e.stopPropagation();
     1033                    return false;
     1034                }
     1035            });
     1036        }
     1037
     1038        /**
     1039         * Validiert alle exprdawc_attributes.
     1040         * Prüft, dass jedes Feld einen non-empty Label hat.
     1041         *
     1042         * @returns {boolean} true wenn Validierung erfolgreich, false wenn Fehler
     1043         */
     1044        validateFields() {
     1045            const $fields = $('#exprdawc_field_body').find('tr.exprdawc_fields_wrapper');
     1046
     1047            if ($fields.length === 0) {
     1048                // Keine Felder vorhanden - das ist ok
     1049                return true;
     1050            }
     1051
     1052            let hasErrors = false;
     1053            const errorFields = [];
     1054
     1055            $fields.each((index, element) => {
     1056                const $row = $(element);
     1057                const $labelInput = $row.find('input.exprdawc_label');
     1058                const labelValue = $labelInput.val().trim();
     1059
     1060                if (labelValue === '') {
     1061                    hasErrors = true;
     1062                    errorFields.push(index + 1); // 1-basiert für Benutzerlesbarkeit
     1063
     1064                    // Visuell markieren des fehlerhaften Feldes
     1065                    $row.addClass('exprdawc-validation-error');
     1066                    $labelInput.addClass('exprdawc-invalid-field');
     1067                } else {
     1068                    // Fehlermarkierung entfernen wenn Feld ok ist
     1069                    $row.removeClass('exprdawc-validation-error');
     1070                    $labelInput.removeClass('exprdawc-invalid-field');
     1071                }
     1072            });
     1073
     1074            if (hasErrors) {
     1075                const fieldCount = errorFields.length;
     1076                const fieldNumbersText = errorFields.join(', ');
     1077                const hasMultipleErrors = fieldCount > 1;
     1078                console.log(exprdawc_admin_meta_boxes.validation_warning)
     1079                const warningMessage = exprdawc_admin_meta_boxes.validation_warning;
     1080                alert(warningMessage);
     1081                return false;
     1082            }
     1083
     1084            return true;
     1085        }
     1086
    10681087    }
    10691088
  • extra-product-data-for-woocommerce/tags/2.0.1/src/assets/js/wc-product-frontend.js

    r3460848 r3469202  
    198198
    199199                    let fieldPrice = 0;
     200                    let adjustmentType = 'fixed';
    200201                    if (fieldType === "select") {
    201202                        const $selectedOption = $(this).find("option:selected");
    202203                        if ($selectedOption.data('price-adjustment')) {
    203204                            fieldPrice = parseFloat($selectedOption.data('price-adjustment')) || 0;
     205                            adjustmentType = $selectedOption.data('price-adjustment-type') || 'fixed';
    204206                        }
    205207                    } else {
    206208                        fieldPrice = parseFloat($(this).data('price-adjustment')) || 0;
     209                        adjustmentType = $(this).data('price-adjustment-type') || 'fixed';
     210                    }
     211
     212                    // Calculate percentage-based price adjustments
     213                    if (adjustmentType === 'percentage' && fieldPrice !== 0) {
     214                        fieldPrice = (basePrice * fieldPrice) / 100;
    207215                    }
    208216
  • extra-product-data-for-woocommerce/tags/2.0.1/src/assets/scss/admin-backend.scss

    r3460848 r3469202  
    423423    content: "\f342";
    424424}
     425
     426/**
     427 * Validation Error Styles
     428 * Markiert Felder mit Validierungsfehlern
     429 */
     430tr.exprdawc-validation-error {
     431    background-color: #fee !important;
     432    box-shadow: inset 0 0 0 1px #f00 !important;
     433   
     434    .exprdawc_fields_table {
     435        border: 1px solid #f00;
     436    }
     437}
     438
     439input.exprdawc-invalid-field {
     440    border-color: #d63638 !important;
     441    background-color: #ffe8e8 !important;
     442    box-shadow: inset 0 0 0 1px #d63638 !important;
     443   
     444    &:focus {
     445        border-color: #d63638 !important;
     446        background-color: #fff !important;
     447        box-shadow: 0 0 0 3px rgba(214, 54, 56, 0.1) !important;
     448    }
     449}
     450
     451/**
     452 * Scrolle zum ersten Fehler bei Validierung
     453 * Hilft dem Nutzer das Problem schnell zu finden
     454 */
     455.exprdawc-validation-error:first-of-type {
     456    animation: pulse-error 0.5s ease-in-out 2;
     457}
     458
     459@keyframes pulse-error {
     460    0%, 100% {
     461        background-color: #fee;
     462    }
     463    50% {
     464        background-color: #ffcccc;
     465    }
     466}
  • extra-product-data-for-woocommerce/tags/2.0.1/src/classes/class-exprdawc-main.php

    r3221376 r3469202  
    2525 */
    2626
     27declare( strict_types=1 );
    2728namespace Triopsi\Exprdawc;
    2829
     
    3031    exit; // Exit if accessed directly.
    3132}
    32 use function Triopsi\Exprdawc\tr_is_woocommerce_active;
     33use Triopsi\Exprdawc\Helper\Exprdawc_Helper;
     34use Triopsi\Exprdawc\Order\Admin\Exprdawc_Admin_Order;
     35use Triopsi\Exprdawc\Order\Customer\Exprdawc_User_Order;
    3336
    3437/**
     
    5760
    5861    /**
    59      * Product Fronted Object Holder.
     62     * Product Frontend Object Holder.
    6063     *
    61      * @var \Product_Page_Fronted
     64     * @var \Product_Page_Frontend
    6265     */
    63     protected $exprdawc_product_fronted = null;
     66    protected $exprdawc_product_frontend = null;
    6467
    6568    /**
     
    7881
    7982    /**
     83     * User Order Object Holder.
     84     *
     85     * @var \User_Order
     86     */
     87    protected $exprdawc_user_order = null;
     88
     89    /**
    8090     * Creates or returns an instance of this class.
    8191     *
     
    90100
    91101    /**
    92      * Register the autoloader.
    93      */
    94     protected function register_autoloader() {
    95         require_once EXPRDAWC_CLASSES . 'class-autoloader.php';
    96         Autoloader::setup( EXPRDAWC_CLASSES, __NAMESPACE__ );
    97     }
    98 
    99     /**
    100102     * Initiate our sub-objects.
    101103     */
    102104    protected function __construct() {
    103 
    104         $this->register_autoloader();
    105 
    106105        // Init Hooks.
    107106        add_action( 'init', array( $this, 'load_components' ), 0 );
     
    132131    public function load_components() {
    133132
    134         if ( tr_is_woocommerce_active() ) {
     133        if ( Exprdawc_Helper::is_woocommerce_active() ) {
    135134
    136135            // Product Create/Edit Page.
    137136            $this->exprdawc_product_backend = new Exprdawc_Product_Page_Backend();
    138137
    139             // Product Product Fronted.
    140             $this->exprdawc_product_fronted = new Exprdawc_Product_Page_Fronted();
     138            // Product Product Frontend.
     139            $this->exprdawc_product_frontend = new Exprdawc_Product_Page_Frontend();
    141140
    142141            // Admin Order Edit Page.
    143142            $this->exprdawc_admin_order_edit = new Exprdawc_Admin_Order();
    144143
    145             // Settings.
     144            // User Order.
     145            $this->exprdawc_user_order = new Exprdawc_User_Order();
     146
     147            // Add Settings in the WooCommerce Settings Page.
    146148            $this->exprdawc_settings = new Exprdawc_Settings();
    147 
    148             // User Order.
    149             new Exprdawc_User_Order();
    150 
    151149        }
    152150    }
     
    159157    public function exprdawc_only_admin_enqueue_scripts() {
    160158        if ( is_admin() ) {
    161             wp_enqueue_style( 'exprdawc-backend-css', EXPRDAWC_ASSETS_CSS . 'admin-backend.css', array(), '1.0.0', 'all' );
    162             wp_enqueue_style( 'form-css', EXPRDAWC_ASSETS_CSS . 'forms.css', array(), '1.0.0', 'all' );
     159            wp_enqueue_style( 'exprdawc-backend-css', EXPRDAWC_ASSETS_CSS . 'admin-backend.css', array(), EXPRDAWC_VERSION, 'all' );
     160            wp_enqueue_style( 'form-css', EXPRDAWC_ASSETS_CSS . 'forms.css', array(), EXPRDAWC_VERSION, 'all' );
    163161        }
    164162    }
  • extra-product-data-for-woocommerce/tags/2.0.1/src/classes/class-exprdawc-product-page-backend.php

    r3460848 r3469202  
    2525 */
    2626
     27declare( strict_types=1 );
    2728namespace Triopsi\Exprdawc;
    2829
     
    3031    exit; // Exit if accessed directly.
    3132}
     33
     34use Triopsi\Exprdawc\Helper\Exprdawc_Helper;
     35
    3236/**
    33  * Class Selection
    34  *
    35  * This class represents a selection of items. It provides methods to add, remove,
    36  * and retrieve items from the selection. The selection can be manipulated and queried
     37 * Class Exprdawc_Product_Page_Backend
     38 *
     39 * This class represents the backend functionality for the product page in the Extra Product Data for WooCommerce plugin.
     40 * It provides methods to add, remove, and retrieve items from the selection. The selection can be manipulated and queried
    3741 * to perform various operations on the contained items.
    3842 *
     
    4751
    4852        // Add custom tab in product edit page.
    49         add_filter( 'woocommerce_product_data_tabs', array( $this, 'exprdawc_add_custom_product_tab' ) );
    50         add_action( 'woocommerce_product_data_panels', array( $this, 'exprdawc_add_custom_product_fields' ) );
    51 
    52         // Save custom fields.
    53         add_action( 'woocommerce_process_product_meta', array( $this, 'exprdawc_save_extra_product_fields' ) );
    54 
    55         // Add Scripts in head and footer.
    56         add_action( 'admin_enqueue_scripts', array( $this, 'exprdawc_show_general_tab' ) );
    57 
    58         // Import custom fields.
    59         add_action( 'wp_ajax_exprdawc_import_custom_fields', array( $this, 'exprdawc_import_custom_fields' ) );
     53        if ( is_admin() ) {
     54            add_filter( 'woocommerce_product_data_tabs', array( $this, 'exprdawc_add_custom_product_tab' ) );
     55            add_action( 'woocommerce_product_data_panels', array( $this, 'exprdawc_add_custom_product_fields' ) );
     56
     57            // Save custom fields.
     58            add_action( 'woocommerce_process_product_meta', array( $this, 'exprdawc_save_extra_product_fields' ) );
     59
     60            // Add Scripts in head and footer.
     61            add_action( 'admin_enqueue_scripts', array( $this, 'exprdawc_show_general_tab' ) );
     62
     63            // Import custom fields.
     64            add_action( 'wp_ajax_exprdawc_import_custom_fields', array( $this, 'exprdawc_import_custom_fields' ) );
     65        }
    6066    }
    6167
     
    7783
    7884    /**
    79      * Add custom fields to the product edit page.
    80      *
    81      * This function is responsible for adding custom fields to the product edit page
    82      * in the WooCommerce admin interface. It ensures that the fields are displayed
    83      * correctly and can be used to store additional product data.
    84      */
    85     public function exprdawc_add_custom_product_fields() {
     85     * Add custom product fields to the product edit page.
     86     *
     87     * This function is hooked to the 'woocommerce_product_data_panels' action and is responsible for
     88     * rendering the HTML for the custom product fields panel in the product edit page.
     89     */
     90    public function exprdawc_add_custom_product_fields(): void {
    8691        global $post;
    87         $product       = wc_get_product( $post );
     92        $post_id = ( $post instanceof \WP_Post ) ? (int) $post->ID : 0;
     93        if ( $post_id <= 0 ) {
     94            return;
     95        }
     96
     97        echo $this->get_custom_product_fields_panel_html( $post_id ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
     98    }
     99
     100    /**
     101     * Get the HTML for the custom product fields panel.
     102     *
     103     * @param int $product_id The ID of the product for which to get the panel HTML.
     104     * @return string The HTML for the custom product fields panel.
     105     */
     106    public function get_custom_product_fields_panel_html( int $product_id ): string {
     107        $product = wc_get_product( $product_id );
     108        if ( ! $product ) {
     109            return '';
     110        }
     111
    88112        $custom_fields = $product->get_meta( '_extra_product_fields', true );
    89         include EXPRDAWC_TEMPLATES . 'html-tab-extra-attributes.php';
     113        if ( ! is_array( $custom_fields ) ) {
     114            $custom_fields = array();
     115        }
     116
     117        ob_start();
     118        Exprdawc_Helper::render_template(
     119            'html-tab-extra-attributes.php',
     120            array(
     121                'product'       => $product,
     122                'custom_fields' => $custom_fields,
     123                'product_id'    => $product_id,
     124            )
     125        );
     126        return (string) ob_get_clean();
    90127    }
    91128
     
    96133     */
    97134    public function exprdawc_show_general_tab() {
    98         wp_enqueue_script( 'exprdawc-wc-meta-boxes-js', EXPRDAWC_ASSETS_JS . 'wc-meta-boxes-product.js', array( 'jquery', 'jquery-ui-sortable' ), '1.0.0', true );
     135        // Enqueue main product meta boxes script.
     136        wp_enqueue_script( 'exprdawc-wc-meta-boxes-js', EXPRDAWC_ASSETS_JS . 'wc-meta-boxes-product.min.js', array( 'jquery', 'jquery-ui-sortable' ), EXPRDAWC_VERSION, true );
     137
     138        // Enqueue import/export modal CSS and JS.
     139        wp_enqueue_style( 'exprdawc-import-export-modal-css', EXPRDAWC_ASSETS_CSS . 'import-export-modal.css', array(), EXPRDAWC_VERSION );
     140        wp_enqueue_script( 'exprdawc-import-export-modal-js', EXPRDAWC_ASSETS_JS . 'import-export-modal.min.js', array( 'jquery' ), EXPRDAWC_VERSION, true );
     141
    99142        wp_localize_script(
    100143            'exprdawc-wc-meta-boxes-js',
     
    103146                'edit_exprdawc_nonce'                  => wp_create_nonce( 'edit_exprdawc_nonce' ),
    104147                'label_placeholder'                    => esc_html__( 'Name of the label', 'extra-product-data-for-woocommerce' ),
     148                'columns'                              => esc_html__( 'Columns', 'extra-product-data-for-woocommerce' ),
    105149                'short_text'                           => esc_html__( 'Short Text', 'extra-product-data-for-woocommerce' ),
    106150                'long_text'                            => esc_html__( 'Long Text', 'extra-product-data-for-woocommerce' ),
     
    203247                'enable_price_adjustment'              => esc_html__( 'Enable price adjustment', 'extra-product-data-for-woocommerce' ),
    204248                'price_adjustment_type'                => esc_html__( 'Price Adjustment Type', 'extra-product-data-for-woocommerce' ),
     249                'validation_warning'                   => esc_html__( 'Warning! No label text (Labels) was found. Please fill all fields with label text before saving.', 'extra-product-data-for-woocommerce' ),
    205250                'price_adjustment_value'               => esc_html__( 'Price Adjustment Value', 'extra-product-data-for-woocommerce' ),
    206251                'fixed'                                => esc_html__( 'Fixed Price', 'extra-product-data-for-woocommerce' ),
     
    208253                'quantity'                             => esc_html__( 'Price per Quantity', 'extra-product-data-for-woocommerce' ),
    209254                'default_selected'                     => esc_html__( 'Default selected', 'extra-product-data-for-woocommerce' ),
     255                'exportTitle'                          => esc_html__( 'Export Custom Fields', 'extra-product-data-for-woocommerce' ),
     256                'importTitle'                          => esc_html__( 'Import Custom Fields', 'extra-product-data-for-woocommerce' ),
     257                'invalidJsonMsg'                       => esc_html__( 'Invalid JSON format. Please check your input.', 'extra-product-data-for-woocommerce' ),
     258                'importingMsg'                         => esc_html__( 'Importing...', 'extra-product-data-for-woocommerce' ),
    210259            )
    211260        );
     
    333382            // Save the custom fields to the product.
    334383            $product->update_meta_data( '_extra_product_fields', $custom_fields );
    335 
    336384        } else {
    337385            // Get the product.
     
    340388            // Delete the custom fields from the product.
    341389            $product->delete_meta_data( '_extra_product_fields' );
    342 
    343390        }
    344391
  • extra-product-data-for-woocommerce/tags/2.0.1/src/classes/class-exprdawc-settings.php

    r3460848 r3469202  
    2525 */
    2626
     27declare( strict_types=1 );
    2728namespace Triopsi\Exprdawc;
    2829
     
    111112                array(
    112113                    'title'   => __( 'Custom Add to CartText', 'extra-product-data-for-woocommerce' ),
    113                     'desc'    => __( 'Enter custom text for the "Add to cart" button if the product has extra product data fields. If not specified, the WooCommerce default will be used.', 'extra-product-data-for-woocommerce' ),
     114                    'desc'    => __( 'Enter custom text for the "Add to cart" button if the product has extra product data fields.', 'extra-product-data-for-woocommerce' ),
    114115                    'id'      => 'exprdawc_custom_add_to_cart_text',
    115                     'default' => '',
     116                    'default' => __( 'Configure Product', 'extra-product-data-for-woocommerce' ),
    116117                    'type'    => 'text',
    117118                ),
  • extra-product-data-for-woocommerce/tags/2.0.1/src/constants.php

    r3460848 r3469202  
    3030
    3131// Useful global constants.
    32 $version = '1.8.0';
     32$version = '2.0.1';
    3333define( 'EXPRDAWC_VERSION', $version );
    3434define( 'EXPRDAWC_PLUGIN_MAIN_FILE', 'extra-product-data-for-woocommerce.php' );
  • extra-product-data-for-woocommerce/tags/2.0.1/src/templates/view/fields/checkbox.php

    r3460848 r3469202  
    11<?php
    22/**
    3  * Created on Tue Nov 26 2024
     3 * Checkbox Field Template (Template Engine Version)
    44 *
    5  * Copyright (c) 2024 IT-Dienstleistungen Drevermann - All Rights Reserved
     5 * Variables available:
     6 * - $field: Complete field configuration
     7 * - $required_string: Required indicator HTML
     8 * - $custom_attributes: Array of custom HTML attributes
    69 *
    7  * @package Extra Product Data for WooCommerce
    8  * @author Daniel Drevermann <info@triopsi.com>
    9  * @copyright Copyright (c) 2024, IT-Dienstleistungen Drevermann
    10  *
    11  * This program is free software: you can redistribute it and/or modify
    12  * it under the terms of the GNU General Public License as published by
    13  * the Free Software Foundation, either version 2 of the License, or
    14  * (at your option) any later version.
    15  *
    16  * This program is distributed in the hope that it will be useful,
    17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    19  * GNU General Public License for more details.
    20  *
    21  * You should have received a copy of the GNU General Public License
    22  * along with this program. If not, see <https://www.gnu.org/licenses/>.
    23  *
    24  * This file is part of the development of WordPress plugins.
     10 * @package Extra_Product_Data_For_WooCommerce\Helper
     11 * @since 1.9.0
    2512 */
     13
     14use Triopsi\Exprdawc\Helper\Exprdawc_Template_Helpers as H;
     15
    2616// phpcs:ignoreFile
    2717if ( ! defined( 'ABSPATH' ) ) {
    2818    exit;
    2919}
    30 echo '<label class="' . esc_attr( implode( ' ', $field_args['label_class'] ) ) . '">' . esc_html( $field_args['label'] ) . $required_string . '</label>';
    31 echo '<span class="' . esc_attr( implode( ' ', $field_args['input_wrapper_class'] ) ) . '">';
    32 if ( isset( $field_args['options'] ) && is_array( $field_args['options'] ) ) {
    33     foreach ( $field_args['options'] as $option ) {
    34         $option_value = $option['value'];
    35         $option_label = $option['label'];
    36         $checked      = in_array( $option_value, (array) explode( ', ', $field_args['value'] ) ) ? 'checked' : '';
    37         $id           = $field_args['id'] . '-' . str_replace( array( ' ', '_' ), '-', $option_value );
    3820
    39         // if option have adjustable price than add price to the label.
    40         $price_adjustment = array();
    41         if ( isset( $option['price_adjustment_value'] ) && $field_args['adjust_price'] ) {
    42             $plus_minus    = $option['price_adjustment_value'] != 0 ? ( $option['price_adjustment_value'] > 0 ? '+' : '-' ) : '';
    43             $option_label .= ' (' . $plus_minus . wc_price( $option['price_adjustment_value'] ) . ')';
    44             // Add custom data attribute to the input field and type.
    45             $price_adjustment[] = 'data-price-adjustment="' . esc_attr( $option['price_adjustment_value'] ) . '"';
    46             $price_adjustment[] = 'data-price-adjustment-type="' . esc_attr( $option['price_adjustment_type'] ) . '"';
    47             // add data label to the input field.
    48             $price_adjustment[] = 'data-label="' . esc_attr( $option_label ) . '"';
    49         }
     21// Alias field_args as field for template.
     22$field = $field_args ?? array();
     23?>
    5024
    51         echo '<div class="exprdawc-checkbox-option">';
    52         echo '<input type="checkbox"
    53             id="' . esc_attr( $id ) . '"
    54             name="' . esc_attr( $field_args['name'] ) . '[]"
    55             value="' . esc_attr( $option_value ) . '"
    56             ' . $checked . '
    57             class="' . esc_attr( implode( ' ', $field_args['input_class'] ) ) . '"
    58             ' . implode( ' ', $custom_attributes ) . '
    59             ' . implode( ' ', $price_adjustment ) . '/>';
     25<label class="<?php echo H::classes( $field['label_class'] ); ?>">
     26    <?php echo H::e( $field['label'] ); ?>
     27    <?php echo $required_string; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
     28</label>
    6029
    61         echo '<label for="' . esc_attr( $id ) . '" class="exprdawc-label-checkbox">' . $option_label . '</label>';
    62         echo '</div>';
    63     }
    64     if ( isset( $field_args['unchecked_value'] ) ) {
    65         echo '<input type="hidden" name="' . esc_attr( $field_args['id'] ) . '[]" value="' . esc_attr( $field_args['unchecked_value'] ) . '" />';
    66     }
    67 }
    68 echo '</span>';
    69 if ( ! empty( $field_args['description'] ) ) {
    70     echo '<span id="' . esc_attr( $field_args['id'] ) . '-description" class="' . esc_attr( implode( ' ', $field_args['description_class'] ) ) . '">' . esc_html( $field_args['description'] ) . '</span>';
    71 }
     30<span class="<?php echo H::classes( $field['input_wrapper_class'] ); ?>">
     31    <?php if ( ! empty( $field['options'] ) && is_array( $field['options'] ) ) : ?>
     32        <?php foreach ( $field['options'] as $option ) : ?>
     33            <?php
     34            $option_value = $option['value'] ?? '';
     35            $option_label = $option['label'] ?? '';
     36            $checked      = H::checked( $field['value'], $option_value );
     37            $option_id    = H::id( $field['id'] . '-' . $option_value );
    7238
    73 // Add the required checbox check with inline js code
    74 if ( $field_args['required'] ) {
    75     ?>
     39            // Build data attributes for price adjustment.
     40            $data_attrs = array();
     41            if ( ! empty( $option['price_adjustment_value'] ) ) {
     42                $data_attrs['price-adjustment']      = $option['price_adjustment_value'];
     43                $data_attrs['price-adjustment-type'] = $option['price_adjustment_type'] ?? 'fixed';
     44                $data_attrs['label']                 = $option_label;
     45            }
     46            ?>
     47
     48            <div class="exprdawc-checkbox-option">
     49                <input type="checkbox"
     50                    id="<?php echo H::attr( $option_id ); ?>"
     51                    name="<?php echo H::attr( $field['name'] ); ?>[]"
     52                    value="<?php echo H::attr( $option_value ); ?>"
     53                    <?php echo $checked; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
     54                    class="<?php echo H::classes( $field['input_class'] ); ?>"
     55                    <?php echo H::join( $custom_attributes ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
     56                    <?php echo H::data_attrs( $data_attrs ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
     57                />
     58                <label for="<?php echo H::attr( $option_id ); ?>" class="exprdawc-label-checkbox">
     59                    <?php echo H::e( $option_label ); ?>
     60                </label>
     61            </div>
     62
     63        <?php endforeach; ?>
     64
     65        <?php if ( isset( $field['unchecked_value'] ) ) : ?>
     66            <input type="hidden"
     67                name="<?php echo H::attr( $field['id'] ); ?>[]"
     68                value="<?php echo H::attr( $field['unchecked_value'] ); ?>"
     69            />
     70        <?php endif; ?>
     71    <?php endif; ?>
     72</span>
     73
     74<?php if ( ! empty( $field['description'] ) ) : ?>
     75    <span id="<?php echo H::attr( $field['id'] ); ?>-description"
     76        class="<?php echo H::classes( $field['description_class'] ); ?>">
     77        <?php echo H::e( $field['description'] ); ?>
     78    </span>
     79<?php endif; ?>
     80
     81<?php if ( ! empty( $field['required'] ) ) : ?>
    7682    <script>
    7783        jQuery(document).ready(function($) {
    78             const $checkboxGroups = $('.<?php echo esc_js( $field_args['id'] . '-input-wrapper' ); ?>, .exprdawc-field-input-wrapper-required');
     84            const $checkboxGroups = $('.<?php echo H::js( $field['id'] . '-input-wrapper' ); ?>, .exprdawc-field-input-wrapper-required');
    7985            $checkboxGroups.each(function () {
    8086                const $checkboxes = $(this).find('input[type="checkbox"]');
     
    8288                    const isChecked = $checkboxes.is(":checked");
    8389                    $checkboxes.prop("required", !isChecked);
    84                 }).trigger('change'); // Trigger change event on page load to set initial state
     90                }).trigger('change');
    8591            });
    8692        });
    8793    </script>
    88     <?php
    89 }
     94<?php endif; ?>
  • extra-product-data-for-woocommerce/tags/2.0.1/src/templates/view/fields/radio.php

    r3460848 r3469202  
    11<?php
    22/**
    3  * Created on Tue Nov 26 2024
     3 * Radio Field Template (Template Engine Version)
    44 *
    5  * Copyright (c) 2024 IT-Dienstleistungen Drevermann - All Rights Reserved
     5 * Variables available:
     6 * - $field: Complete field configuration
     7 * - $required_string: Required indicator HTML
     8 * - $custom_attributes: Array of custom HTML attributes
    69 *
    7  * @package Extra Product Data for WooCommerce
    8  * @author Daniel Drevermann <info@triopsi.com>
    9  * @copyright Copyright (c) 2024, IT-Dienstleistungen Drevermann
    10  *
    11  * This program is free software: you can redistribute it and/or modify
    12  * it under the terms of the GNU General Public License as published by
    13  * the Free Software Foundation, either version 2 of the License, or
    14  * (at your option) any later version.
    15  *
    16  * This program is distributed in the hope that it will be useful,
    17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    19  * GNU General Public License for more details.
    20  *
    21  * You should have received a copy of the GNU General Public License
    22  * along with this program. If not, see <https://www.gnu.org/licenses/>.
    23  *
    24  * This file is part of the development of WordPress plugins.
     10 * @package Extra_Product_Data_For_WooCommerce
     11 * @since 1.9.0
    2512 */
     13
     14use Triopsi\Exprdawc\Helper\Exprdawc_Template_Helpers as H;
     15
    2616// phpcs:ignoreFile
    2717if ( ! defined( 'ABSPATH' ) ) {
    2818    exit;
    2919}
    30 echo '<label class="' . esc_attr( implode( ' ', $field_args['label_class'] ) ) . '">' . esc_html( $field_args['label'] ) . $required_string . '</label>';
    31 echo '<span class="' . esc_attr( implode( ' ', $field_args['input_wrapper_class'] ) ) . '">';
    32 if ( isset( $field_args['options'] ) && is_array( $field_args['options'] ) ) {
    33     foreach ( $field_args['options'] as $option ) {
    34         $option_value = $option['value'];
    35         $option_label = $option['label'];
    36         $checked      = in_array( $option_value, (array) $field_args['value'] ) ? 'checked' : '';
    37         $id           = $field_args['id'] . '-' . str_replace( array( ' ', '_' ), '-', $option_value );
    3820
    39         // if option have adjustable price than add price to the label.
    40         $price_adjustment = array();
    41         if ( isset( $option['price_adjustment_value'] ) && $field_args['adjust_price'] ) {
    42             $plus_minus    = $option['price_adjustment_value'] != 0 ? ( $option['price_adjustment_value'] > 0 ? '+' : '-' ) : '';
    43             $option_label .= ' (' . $plus_minus . wc_price( $option['price_adjustment_value'] ) . ')';
    44             // Add custom data attribute to the input field and type.
    45             $price_adjustment[] = 'data-price-adjustment="' . esc_attr( $option['price_adjustment_value'] ) . '"';
    46             $price_adjustment[] = 'data-price-adjustment-type="' . esc_attr( $option['price_adjustment_type'] ) . '"';
    47             // add data label to the input field.
    48             $price_adjustment[] = 'data-label="' . esc_attr( $option_label ) . '"';
    49         }
     21// Alias field_args as field for template.
     22$field = $field_args ?? array();
     23?>
    5024
    51         echo '<div class="exprdawc-checkbox-option">';
    52         echo '<input type="radio"
    53             id="' . esc_attr( $id ) . '"
    54             name="' . esc_attr( $field_args['name'] ) . '[]"
    55             value="' . esc_attr( $option_value ) . '"
    56             ' . $checked . '
    57             class="' . esc_attr( implode( ' ', $field_args['input_class'] ) ) . '"
    58             ' . implode( ' ', $custom_attributes ) . '
    59             ' . implode( ' ', $price_adjustment ) . '/>';
     25<label class="<?php echo H::classes( $field['label_class'] ); ?>">
     26    <?php echo H::e( $field['label'] ); ?>
     27    <?php echo $required_string; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
     28</label>
    6029
    61         echo '<label for="' . esc_attr( $id ) . '" class="exprdawc-label-checkbox">' . $option_label . '</label>';
    62         echo '</div>';
    63     }
    64 }
    65 echo '</span>';
    66 if ( ! empty( $field_args['description'] ) ) {
    67     echo '<span id="' . esc_attr( $field_args['id'] ) . '-description" class="' . esc_attr( implode( ' ', $field_args['description_class'] ) ) . '">' . esc_html( $field_args['description'] ) . '</span>';
    68 }
     30<span class="<?php echo H::classes( $field['input_wrapper_class'] ); ?>">
     31    <?php if ( ! empty( $field['options'] ) && is_array( $field['options'] ) ) : ?>
     32        <?php foreach ( $field['options'] as $option ) : ?>
     33            <?php
     34            $option_value = $option['value'] ?? '';
     35            $option_label = $option['label'] ?? '';
     36            $checked      = H::checked( $field['value'] ?? '', $option_value );
     37            $option_id    = H::id( $field['id'] . '-' . $option_value );
     38
     39            // Build data attributes for price adjustment.
     40            $data_attrs = array();
     41            if ( ! empty( $option['price_adjustment_value'] ) ) {
     42                $data_attrs['price-adjustment']      = $option['price_adjustment_value'];
     43                $data_attrs['price-adjustment-type'] = $option['price_adjustment_type'] ?? 'fixed';
     44                $data_attrs['label']                 = $option_label;
     45            }
     46            ?>
     47
     48            <div class="exprdawc-radio-option">
     49                <input type="radio"
     50                    id="<?php echo H::attr( $option_id ); ?>"
     51                    name="<?php echo H::attr( $field['name'] ); ?>"
     52                    value="<?php echo H::attr( $option_value ); ?>"
     53                    <?php echo $checked; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
     54                    class="<?php echo H::classes( $field['input_class'] ); ?>"
     55                    <?php echo H::join( $custom_attributes ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
     56                    <?php echo H::data_attrs( $data_attrs ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
     57                />
     58                <label for="<?php echo H::attr( $option_id ); ?>" class="exprdawc-label-radio">
     59                    <?php echo H::e( $option_label ); ?>
     60                </label>
     61            </div>
     62
     63        <?php endforeach; ?>
     64    <?php endif; ?>
     65</span>
     66
     67<?php if ( ! empty( $field['description'] ) ) : ?>
     68    <span id="<?php echo H::attr( $field['id'] ); ?>-description"
     69        class="<?php echo H::classes( $field['description_class'] ); ?>">
     70        <?php echo H::e( $field['description'] ); ?>
     71    </span>
     72<?php endif; ?>
  • extra-product-data-for-woocommerce/tags/2.0.1/src/templates/view/fields/select.php

    r3460848 r3469202  
    11<?php
    22/**
    3  * Created on Tue Nov 26 2024
     3 * Select Field Template (Template Engine Version)
    44 *
    5  * Copyright (c) 2024 IT-Dienstleistungen Drevermann - All Rights Reserved
     5 * Variables available:
     6 * - $field: Complete field configuration
     7 * - $required_string: Required indicator HTML
     8 * - $custom_attributes: Array of custom HTML attributes
    69 *
    7  * @package Extra Product Data for WooCommerce
    8  * @author Daniel Drevermann <info@triopsi.com>
    9  * @copyright Copyright (c) 2024, IT-Dienstleistungen Drevermann
    10  *
    11  * This program is free software: you can redistribute it and/or modify
    12  * it under the terms of the GNU General Public License as published by
    13  * the Free Software Foundation, either version 2 of the License, or
    14  * (at your option) any later version.
    15  *
    16  * This program is distributed in the hope that it will be useful,
    17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    19  * GNU General Public License for more details.
    20  *
    21  * You should have received a copy of the GNU General Public License
    22  * along with this program. If not, see <https://www.gnu.org/licenses/>.
    23  *
    24  * This file is part of the development of WordPress plugins.
     10 * @package Extra_Product_Data_For_WooCommerce
     11 * @since 1.9.0
    2512 */
     13
     14use Triopsi\Exprdawc\Helper\Exprdawc_Template_Helpers as H;
     15
    2616// phpcs:ignoreFile
    2717if ( ! defined( 'ABSPATH' ) ) {
    2818    exit;
    2919}
    30 echo '<label for="' . esc_attr( $field_args['id'] ) . '" class="' . esc_attr( implode( ' ', $field_args['label_class'] ) ) . '">' . esc_html( $field_args['label'] ) . $required_string . '</label>';
    31 echo '<span class="' . esc_attr( implode( ' ', $field_args['input_wrapper_class'] ) ) . '">';
    32 if ( isset( $field_args['options'] ) && is_array( $field_args['options'] ) ) {
    33     echo '<select class="select ' . esc_attr( implode( ' ', $field_args['input_class'] ) ) . '"
    34     id="' . esc_attr( $field_args['id'] ) . '"
    35     name="' . esc_attr( $field_args['name'] ) . '"
    36     ' . implode( ' ', $custom_attributes ) . '>';
    3720
    38     // If placeholder is set, add it as an option.
    39     if ( ! empty( $field_args['placeholder'] ) ) {
    40         echo '<option value="" disabled selected>' . esc_html( $field_args['placeholder'] ) . '</option>';
    41     }
    42     foreach ( $field_args['options'] as $option ) {
    43         $option_value = $option['value'];
    44         $option_label = $option['label'];
    45         $selected     = selected( $field_args['value'], $option_value, false );
    46         // if option have adjustable price than add price to the label.
    47         $price_adjustment = array();
    48         if ( isset( $option['price_adjustment_value'] ) && $field_args['adjust_price'] ) {
    49             $plus_minus    = $option['price_adjustment_value'] != 0 ? ( $option['price_adjustment_value'] > 0 ? '+' : '-' ) : '';
    50             $option_label .= ' (' . $plus_minus . wc_price( $option['price_adjustment_value'] ) . ')';
    51             // Add custom data attribute to the input field and type.
    52             $price_adjustment[] = 'data-price-adjustment="' . esc_attr( $option['price_adjustment_value'] ) . '"';
    53             $price_adjustment[] = 'data-price-adjustment-type="' . esc_attr( $option['price_adjustment_type'] ) . '"';
    54             // add data label to the input field.
    55             $price_adjustment[] = 'data-label="' . esc_attr( $option_label ) . '"';
    56         }
     21// Alias field_args as field for template.
     22$field = $field_args ?? array();
     23?>
    5724
    58         echo '<option value="' . esc_attr( $option_value ) . '" ' . $selected . ' ' . implode( ' ', $price_adjustment ) . '>' . $option_label . '</option>';
    59     }
    60     echo '</select>';
    61 }
    62 echo '</span>';
    63 if ( ! empty( $field_args['description'] ) ) {
    64     echo '<span id="' . esc_attr( $field_args['id'] ) . '-description" class="' . esc_attr( implode( ' ', $field_args['description_class'] ) ) . '">' . esc_html( $field_args['description'] ) . '</span>';
    65 }
     25<label for="<?php echo H::attr( $field['id'] ); ?>"
     26    class="<?php echo H::classes( $field['label_class'] ); ?>">
     27    <?php echo H::e( $field['label'] ); ?>
     28    <?php echo $required_string; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
     29</label>
     30
     31<span class="<?php echo H::classes( $field['input_wrapper_class'] ); ?>">
     32    <?php if ( ! empty( $field['options'] ) && is_array( $field['options'] ) ) : ?>
     33        <select class="select <?php echo H::classes( $field['input_class'] ); ?>"
     34            id="<?php echo H::attr( $field['id'] ); ?>"
     35            name="<?php echo H::attr( $field['name'] ); ?>"
     36            <?php echo H::join( $custom_attributes ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
     37        >
     38            <?php if ( ! empty( $field['placeholder'] ) ) : ?>
     39                <option value="" disabled selected>
     40                    <?php echo H::e( $field['placeholder'] ); ?>
     41                </option>
     42            <?php endif; ?>
     43
     44            <?php foreach ( $field['options'] as $option ) : ?>
     45                <?php
     46                $option_value = $option['value'] ?? '';
     47                $option_label = $option['label'] ?? '';
     48                $selected     = H::selected( $field['value'] ?? '', $option_value );
     49
     50                // Build data attributes for price adjustment.
     51                $data_attrs = array();
     52                if ( ! empty( $option['price_adjustment_value'] ) ) {
     53                    $data_attrs['price-adjustment']      = $option['price_adjustment_value'];
     54                    $data_attrs['price-adjustment-type'] = $option['price_adjustment_type'] ?? 'fixed';
     55                    $data_attrs['label']                 = $option_label;
     56                }
     57                ?>
     58
     59                <option value="<?php echo H::attr( $option_value ); ?>"
     60                    <?php echo $selected; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
     61                    <?php echo H::data_attrs( $data_attrs ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
     62                >
     63                    <?php echo H::e( $option_label ); ?>
     64                </option>
     65            <?php endforeach; ?>
     66        </select>
     67    <?php endif; ?>
     68</span>
     69
     70<?php if ( ! empty( $field['description'] ) ) : ?>
     71    <span id="<?php echo H::attr( $field['id'] ); ?>-description"
     72        class="<?php echo H::classes( $field['description_class'] ); ?>">
     73        <?php echo H::e( $field['description'] ); ?>
     74    </span>
     75<?php endif; ?>
  • extra-product-data-for-woocommerce/tags/2.0.1/src/templates/view/fields/text.php

    r3460848 r3469202  
    11<?php
    22/**
    3  * Created on Tue Nov 26 2024
     3 * Text Field Template (Template Engine Version)
    44 *
    5  * Copyright (c) 2024 IT-Dienstleistungen Drevermann - All Rights Reserved
     5 * Variables available:
     6 * - $field: Complete field configuration
     7 * - $required_string: Required indicator HTML
     8 * - $custom_attributes: Array of custom HTML attributes
    69 *
    7  * @package Extra Product Data for WooCommerce
    8  * @author Daniel Drevermann <info@triopsi.com>
    9  * @copyright Copyright (c) 2024, IT-Dienstleistungen Drevermann
    10  *
    11  * This program is free software: you can redistribute it and/or modify
    12  * it under the terms of the GNU General Public License as published by
    13  * the Free Software Foundation, either version 2 of the License, or
    14  * (at your option) any later version.
    15  *
    16  * This program is distributed in the hope that it will be useful,
    17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    19  * GNU General Public License for more details.
    20  *
    21  * You should have received a copy of the GNU General Public License
    22  * along with this program. If not, see <https://www.gnu.org/licenses/>.
    23  *
    24  * This file is part of the development of WordPress plugins.
     10 * @package Extra_Product_Data_For_WooCommerce
     11 * @since 1.9.0
    2512 */
     13
     14use Triopsi\Exprdawc\Helper\Exprdawc_Template_Helpers as H;
     15
    2616// phpcs:ignoreFile
    2717if ( ! defined( 'ABSPATH' ) ) {
    2818    exit;
    2919}
    30 echo '<label for="' . esc_attr( $field_args['id'] ) . '" class="' . esc_attr( implode( ' ', $field_args['label_class'] ) ) . '">' . esc_html( $field_args['label'] ) . $required_string . '</label>';
    31 echo '<span class="' . esc_attr( implode( ' ', $field_args['input_wrapper_class'] ) ) . '">';
    32 echo '<input type="' . esc_attr( $field_args['type'] ) . '"
    33     class="' . esc_attr( implode( ' ', $field_args['input_class'] ) ) . '"
    34     name="' . esc_attr( $field_args['name'] ) . '"
    35     id="' . esc_attr( $field_args['id'] ) . '"
    36     placeholder="' . esc_attr( $field_args['placeholder'] ) . '"
    37     value="' . esc_attr( $field_args['value'] ) . '"
    38     ' . implode( ' ', $custom_attributes ) . ' />';
    3920
    40 if ( ! empty( $field_args['description'] ) ) {
    41     echo '<span id="' . esc_attr( $field_args['id'] ) . '-description" class="' . esc_attr( implode( ' ', $field_args['description_class'] ) ) . '">' . esc_html( $field_args['description'] ) . '</span>';
    42 }
    43 echo '</span>';
     21// Alias field_args as field for template.
     22$field = $field_args ?? array();
     23?>
     24
     25<label for="<?php echo H::attr( $field['id'] ); ?>"
     26    class="<?php echo H::classes( $field['label_class'] ); ?>">
     27    <?php echo H::e( $field['label'] ); ?>
     28    <?php echo $required_string; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
     29</label>
     30
     31<span class="<?php echo H::classes( $field['input_wrapper_class'] ); ?>">
     32    <input type="<?php echo H::attr( $field['type'] ); ?>"
     33        class="<?php echo H::classes( $field['input_class'] ); ?>"
     34        name="<?php echo H::attr( $field['name'] ); ?>"
     35        id="<?php echo H::attr( $field['id'] ); ?>"
     36        placeholder="<?php echo H::attr( $field['placeholder'] ?? '' ); ?>"
     37        value="<?php echo H::attr( $field['value'] ?? '' ); ?>"
     38        <?php echo H::join( $custom_attributes ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
     39    />
     40
     41    <?php if ( ! empty( $field['description'] ) ) : ?>
     42        <span id="<?php echo H::attr( $field['id'] ); ?>-description"
     43            class="<?php echo H::classes( $field['description_class'] ); ?>">
     44            <?php echo H::e( $field['description'] ); ?>
     45        </span>
     46    <?php endif; ?>
     47</span>
  • extra-product-data-for-woocommerce/tags/2.0.1/src/templates/view/fields/textarea.php

    r3460848 r3469202  
    11<?php
    22/**
    3  * Created on Tue Nov 26 2024
     3 * Textarea Field Template (Template Engine Version)
    44 *
    5  * Copyright (c) 2024 IT-Dienstleistungen Drevermann - All Rights Reserved
     5 * Variables available:
     6 * - $field: Complete field configuration
     7 * - $required_string: Required indicator HTML
     8 * - $custom_attributes: Array of custom HTML attributes
    69 *
    7  * @package Extra Product Data for WooCommerce
    8  * @author Daniel Drevermann <info@triopsi.com>
    9  * @copyright Copyright (c) 2024, IT-Dienstleistungen Drevermann
    10  *
    11  * This program is free software: you can redistribute it and/or modify
    12  * it under the terms of the GNU General Public License as published by
    13  * the Free Software Foundation, either version 2 of the License, or
    14  * (at your option) any later version.
    15  *
    16  * This program is distributed in the hope that it will be useful,
    17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    19  * GNU General Public License for more details.
    20  *
    21  * You should have received a copy of the GNU General Public License
    22  * along with this program. If not, see <https://www.gnu.org/licenses/>.
    23  *
    24  * This file is part of the development of WordPress plugins.
     10 * @package Extra_Product_Data_For_WooCommerce
     11 * @since 1.9.0
    2512 */
     13
     14use Triopsi\Exprdawc\Helper\Exprdawc_Template_Helpers as H;
     15
    2616// phpcs:ignoreFile
    2717if ( ! defined( 'ABSPATH' ) ) {
     
    2919}
    3020
    31 echo '<label for="' . esc_attr( $field_args['id'] ) . '" class="' . esc_attr( implode( ' ', $field_args['label_class'] ) ) . '">' . esc_html( $field_args['label'] ) . $required_string . '</label>';
    32 echo '<span class="' . esc_attr( implode( ' ', $field_args['input_wrapper_class'] ) ) . '">';
    33 echo '<textarea
    34     name="' . esc_attr( $field_args['name'] ) . '"
    35     class="' . esc_attr( implode( ' ', $field_args['input_class'] ) ) . '"
    36     id="' . esc_attr( $field_args['id'] ) . '"
    37     placeholder="' . esc_attr( $field_args['placeholder'] ) . '" ' .
    38     implode( ' ', $custom_attributes ) . '>' .
    39     esc_textarea( $field_args['value'] ) .
    40     '</textarea>';
    41 if ( ! empty( $field_args['description'] ) ) {
    42     echo '<span id="' . esc_attr( $field_args['id'] ) . '-description" class="' . esc_attr( implode( ' ', $field_args['description_class'] ) ) . '">' . esc_html( $field_args['description'] ) . '</span>';
    43 }
    44 echo '</span>';
     21// Alias field_args as field for template.
     22$field = $field_args ?? array();
     23?>
     24
     25<label for="<?php echo H::attr( $field['id'] ); ?>"
     26    class="<?php echo H::classes( $field['label_class'] ); ?>">
     27    <?php echo H::e( $field['label'] ); ?>
     28    <?php echo $required_string; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
     29</label>
     30
     31<span class="<?php echo H::classes( $field['input_wrapper_class'] ); ?>">
     32    <textarea name="<?php echo H::attr( $field['name'] ); ?>"
     33        class="<?php echo H::classes( $field['input_class'] ); ?>"
     34        id="<?php echo H::attr( $field['id'] ); ?>"
     35        placeholder="<?php echo H::attr( $field['placeholder'] ?? '' ); ?>"
     36        <?php echo H::join( $custom_attributes ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
     37    ><?php echo H::textarea( $field['value'] ?? '' ); ?></textarea>
     38
     39    <?php if ( ! empty( $field['description'] ) ) : ?>
     40        <span id="<?php echo H::attr( $field['id'] ); ?>-description"
     41            class="<?php echo H::classes( $field['description_class'] ); ?>">
     42            <?php echo H::e( $field['description'] ); ?>
     43        </span>
     44    <?php endif; ?>
     45</span>
  • extra-product-data-for-woocommerce/tags/2.0.1/src/templates/view/html-tab-extra-attributes.php

    r3460848 r3469202  
    2929}
    3030?>
    31 <input type="hidden" id="exprdawc_export_string" name="exprdawc_export_string" value="<?php echo $custom_fields ? wc_esc_json( json_encode( $custom_fields ) ) : ''; // phpcs:ignore ?>" />
     31<input type="hidden" id="exprdawc_export_string" name="exprdawc_export_string" value="<?php echo $args['custom_fields'] ? wc_esc_json( json_encode( $args['custom_fields'] ) ) : ''; // phpcs:ignore ?>" />
     32
     33<?php
     34// Include the import/export modal template.
     35require EXPRDAWC_TEMPLATES . 'modal-import-export.php';
     36?>
     37
    3238<div id="extra-product-data" class="panel woocommerce_options_panel exprdawc_panel_wrapper">
    3339    <div class="toolbar toolbar-top">
     
    4551                <tbody id="exprdawc_field_body">
    4652                <?php
    47                 if ( ! empty( $custom_fields ) ) {
     53                if ( ! empty( $args['custom_fields'] ) ) {
    4854                    $all_fields = array();
    4955                    // Loop through all fields and include the template.
    50                     foreach ( $custom_fields as $index => $field ) {
     56                    foreach ( $args['custom_fields'] as $index => $field ) {
    5157                        $all_fields[ $field['label'] ] = $field['label'];
    5258                    }
    53                     foreach ( $custom_fields as $index => $field ) {
     59                    foreach ( $args['custom_fields'] as $index => $field ) {
    5460                        $field['price_adjustment_type'] = isset( $field['price_adjustment_type'] ) ? $field['price_adjustment_type'] : '';
    5561                        echo '<tr class="exprdawc_fields_wrapper">';
  • extra-product-data-for-woocommerce/trunk/assets/css/admin-backend.css

    r3460848 r3469202  
    1 #extra-product-data{padding:10px}table.exprdawc_attribute_table td{vertical-align:middle!important}table.exprdawc_attribute_table td.exprdawc_attribute_require_checkbox label{padding-top:15px}table.exprdawc_field_table{border-collapse:collapse;width:100%}table.exprdawc_field_table th{background-color:#f1f1f1;font-weight:700;padding:10px;text-align:left}table.exprdawc_field_table tr:nth-child(2n){background-color:#f9f9f9}table.exprdawc_field_table tr.exprdawc_fields_wrapper{border-bottom:1px solid #ddd}table.exprdawc_field_table tr.exprdawc_fields_wrapper:hover{background-color:#f1f1f1}table.exprdawc_field_table tr.exprdawc_fields_wrapper:last-child{border-bottom:none}table.exprdawc_field_table td{padding:0}table.exprdawc_field_table tfoot tr{background-color:#fafafa;border:1px solid #ccc}table.exprdawc_field_table tfoot td{padding:10px;text-align:center;vertical-align:middle}table.exprdawc_field_table tfoot td.exprdawc_add_field_col{text-align:left}table.exprdawc_field_table tfoot td.exprdawc_export_col{text-align:right}table.exprdawc_field_table tfoot .button{line-height:13px;padding:5px}table.exprdawc_fields_table{border-collapse:collapse;width:100%}table.exprdawc_fields_table tr{border:0}table.exprdawc_fields_table tbody td{padding:10px;text-align:left;vertical-align:middle;white-space:nowrap;width:auto}table.exprdawc_fields_table tbody td input[type=number],table.exprdawc_fields_table tbody td input[type=text],table.exprdawc_fields_table tbody td select,table.exprdawc_fields_table tbody td textarea{border:1px solid #ccc;border-radius:4px;box-sizing:border-box;padding:5px;width:100%}table.exprdawc_fields_table tbody td select{text-overflow:ellipsis}table.exprdawc_fields_table tbody td button.add_rule,table.exprdawc_fields_table tbody td button.exprdawc_copy_custom_field,table.exprdawc_fields_table tbody td button.exprdawc_remove_custom_field,table.exprdawc_fields_table tbody td button.remove_rule{line-height:13px;padding:5px}table.exprdawc_fields_table tbody td.move i{cursor:move}table.exprdawc_fields_table tbody td.cl-arr i{cursor:pointer}table.exprdawc_settings_table{width:100%}table.exprdawc_settings_table label.exprdawc_label{align-items:center;display:flex;float:none;margin:5px 0;padding:0;text-align:left;width:auto}table.exprdawc_settings_table label.exprdawc_label .checkbox{margin-right:5px!important}table.exprdawc_settings_table td{padding:10px;vertical-align:middle}table.exprdawc_options_table{border:1px solid #ccc;border-collapse:collapse;margin-top:10px;width:100%}table.exprdawc_options_table td,table.exprdawc_options_table th{border-bottom:1px solid #ddd;padding:10px;text-align:left}table.exprdawc_options_table th{background-color:#f1f1f1}table.exprdawc_options_table tr:hover{background-color:#f9f9f9}table.exprdawc_options_table .button{background-color:#0073aa;border:none;border-radius:4px;color:#fff;cursor:pointer;padding:5px 10px}table.exprdawc_options_table .button:hover{background-color:#005a87;color:#fff}.exprdawc_attribute h3 .sort{cursor:move;float:right;font-size:15px;font-weight:400;height:26px;margin-right:.5em;text-align:center;vertical-align:middle;width:17px}.exprdawc_attribute h3 .sort:before{color:#999;content:"";display:block;float:left;font-family:Dashicons;height:100%;line-height:28px;text-align:center;width:17px}.exprdawc_attribute h3 .sort:hover:before{color:#777}.exprdawc_attribute h3:hover .sort,.exprdawc_attribute.ui-sortable-helper .sort{visibility:visible}.exprdawc_attribute.wc-metabox.postbox{border-left:0;border-right:0;border-top:0}.exprdawc_panel{display:block}.exprdawc_panel p.description{margin:0}.exprdawc_panel h2{font-size:1.5em!important;padding:0 0 10px!important}.exprdawc_panel .wc-metabox{background:#fff;border-bottom:1px solid #eee;margin:0!important}.exprdawc_panel .wc-metabox.exprdawc_attribute h3{cursor:pointer;padding:.5em .75em .5em 1em!important}.exprdawc_panel .wc-metabox.exprdawc_attribute h3 .sort,.exprdawc_panel .wc-metabox.exprdawc_attribute h3 a.delete,.exprdawc_panel .wc-metabox.exprdawc_attribute h3 a.edit{margin-top:.25em}#woocommerce-coupon-data ul.wc-tabs li.custom_fields_options a:before,#woocommerce-product-data ul.wc-tabs li.custom_fields_options a:before,.woocommerce ul.wc-tabs li.custom_fields_options a:before{content:"";font-family:Dashicons}.exprdawc_conditional_logic_table{border-collapse:collapse;margin-bottom:20px;width:100%}.exprdawc_conditional_logic_table td,.exprdawc_conditional_logic_table th{border:1px solid #ddd;padding:10px;text-align:left}.exprdawc_conditional_logic_table th{background-color:#f9f9f9;font-weight:700}.exprdawc_conditional_logic_table .exprdawc_label{display:block;font-weight:700;margin-bottom:5px}.exprdawc_conditional_logic_table .exprdawc_input{border:1px solid #ccc;border-radius:4px;box-sizing:border-box;padding:5px;width:100%}.exprdawc_conditional_logic_table .exprdawc_checkbox{width:auto}.exprdawc_conditional_logic_table .exprdawc_textarea{border:1px solid #ccc;border-radius:4px;padding:8px;width:100%}.exprdawc_conditional_logic_table .exprdawc_no_entry_message{color:#a00;font-weight:700}.exprdawc_conditional_logic_table h2{text-align:left;text-transform:uppercase}.exprdawc_conditional_logic_table .exprdawc_rule_group{background-color:#f9f9f9;border:1px solid #ddd;border-radius:4px;margin-bottom:10px;padding:10px}.exprdawc_conditional_logic_table .exprdawc_rule_group .exprdawc_rule{align-items:center;display:flex;margin-bottom:10px}.exprdawc_conditional_logic_table .exprdawc_rule_group .exprdawc_rule .exprdawc_input{margin-right:10px}.exprdawc_conditional_logic_table .exprdawc_rule_group .exprdawc_rule .button{margin-left:10px}.exprdawc_conditional_logic_table .exprdawc_rule_group .add_rule_group{margin-top:10px}.exprdawc_no_entry_message{background:#fafafa;border:1px solid #c3c4c7;border-bottom:none;color:#5b5b5b;display:block;margin:10px 0 0;padding-bottom:1em;padding-top:75px;position:relative;text-align:center}.exprdawc_no_entry_message:before{color:#6c6c6c;content:"";font-family:Dashicons;font-size:70px;left:50%;position:absolute;top:0;transform:translateX(-50%)}a.exprdawc-export,a.exprdawc-import{color:#0073aa;font-size:small;margin:0 5px;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}a.exprdawc-export:before,a.exprdawc-import:before{font-family:Dashicons;margin-right:5px;position:relative}a.exprdawc-export:hover,a.exprdawc-import:hover{color:#005a87;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}a.exprdawc-export:before{content:""}a.exprdawc-import:before{content:""}
     1#extra-product-data{padding:10px 10px}table.exprdawc_attribute_table td{vertical-align:middle !important}table.exprdawc_attribute_table td.exprdawc_attribute_require_checkbox label{padding-top:15px}table.exprdawc_field_table{width:100%;border-collapse:collapse}table.exprdawc_field_table th{background-color:#f1f1f1;font-weight:bold;padding:10px;text-align:left}table.exprdawc_field_table tr:nth-child(even){background-color:#f9f9f9}table.exprdawc_field_table tr.exprdawc_fields_wrapper{border-bottom:1px solid #ddd}table.exprdawc_field_table tr.exprdawc_fields_wrapper:hover{background-color:#f1f1f1}table.exprdawc_field_table tr.exprdawc_fields_wrapper:last-child{border-bottom:none}table.exprdawc_field_table td{padding:0px}table.exprdawc_field_table tfoot tr{background-color:#fafafa;border:1px solid #ccc}table.exprdawc_field_table tfoot td{padding:10px;text-align:center;vertical-align:middle}table.exprdawc_field_table tfoot td.exprdawc_add_field_col{text-align:left}table.exprdawc_field_table tfoot td.exprdawc_export_col{text-align:right}table.exprdawc_field_table tfoot .button{padding:5px;line-height:13px}table.exprdawc_fields_table{width:100%;border-collapse:collapse}table.exprdawc_fields_table tr{border:0px}table.exprdawc_fields_table tbody td{vertical-align:middle;padding:10px;text-align:left;width:auto;white-space:nowrap}table.exprdawc_fields_table tbody td input[type=text],table.exprdawc_fields_table tbody td input[type=number],table.exprdawc_fields_table tbody td textarea{width:100%;padding:5px;border:1px solid #ccc;border-radius:4px;box-sizing:border-box}table.exprdawc_fields_table tbody td select{width:100%;padding:5px;border:1px solid #ccc;border-radius:4px;box-sizing:border-box;text-overflow:ellipsis}table.exprdawc_fields_table tbody td button.add_rule,table.exprdawc_fields_table tbody td button.exprdawc_remove_custom_field,table.exprdawc_fields_table tbody td button.exprdawc_copy_custom_field,table.exprdawc_fields_table tbody td button.remove_rule{padding:5px;line-height:13px}table.exprdawc_fields_table tbody td.move i{cursor:move}table.exprdawc_fields_table tbody td.cl-arr i{cursor:pointer}table.exprdawc_settings_table{width:100%}table.exprdawc_settings_table label.exprdawc_label{float:none;padding:0px;margin:5px 0px;text-align:left;display:flex;width:auto;align-items:center}table.exprdawc_settings_table label.exprdawc_label .checkbox{margin-right:5px !important}table.exprdawc_settings_table td{vertical-align:middle;padding:10px}table.exprdawc_options_table{width:100%;border-collapse:collapse;margin-top:10px;border:1px solid #ccc}table.exprdawc_options_table th,table.exprdawc_options_table td{padding:10px;text-align:left;border-bottom:1px solid #ddd}table.exprdawc_options_table th{background-color:#f1f1f1}table.exprdawc_options_table tr:hover{background-color:#f9f9f9}table.exprdawc_options_table .button{padding:5px 10px;border:none;border-radius:4px;background-color:#0073aa;color:#fff;cursor:pointer}table.exprdawc_options_table .button:hover{background-color:#005a87;color:#fff}.exprdawc_attribute h3 .sort{width:17px;height:26px;cursor:move;float:right;font-size:15px;font-weight:400;margin-right:.5em;text-align:center;vertical-align:middle}.exprdawc_attribute h3 .sort::before{content:"";font-family:"Dashicons";text-align:center;line-height:28px;color:#999;display:block;width:17px;float:left;height:100%}.exprdawc_attribute h3 .sort:hover::before{color:#777}.exprdawc_attribute h3:hover .sort,.exprdawc_attribute.ui-sortable-helper .sort{visibility:visible}.exprdawc_attribute.wc-metabox.postbox{border-top:0px;border-left:0px;border-right:0px}.exprdawc_panel{display:block}.exprdawc_panel p.description{margin:0}.exprdawc_panel h2{font-size:1.5em !important;padding:0px 0px 10px 0px !important}.exprdawc_panel .wc-metabox{background:#fff;border-bottom:1px solid #eee;margin:0 !important}.exprdawc_panel .wc-metabox.exprdawc_attribute h3{cursor:pointer;padding:.5em .75em .5em 1em !important}.exprdawc_panel .wc-metabox.exprdawc_attribute h3 a.delete,.exprdawc_panel .wc-metabox.exprdawc_attribute h3 a.edit,.exprdawc_panel .wc-metabox.exprdawc_attribute h3 .sort{margin-top:.25em}#woocommerce-product-data ul.wc-tabs li.custom_fields_options a::before,#woocommerce-coupon-data ul.wc-tabs li.custom_fields_options a::before,.woocommerce ul.wc-tabs li.custom_fields_options a::before{font-family:"Dashicons";content:""}.exprdawc_conditional_logic_table{width:100%;border-collapse:collapse;margin-bottom:20px}.exprdawc_conditional_logic_table th,.exprdawc_conditional_logic_table td{padding:10px;border:1px solid #ddd;text-align:left}.exprdawc_conditional_logic_table th{background-color:#f9f9f9;font-weight:bold}.exprdawc_conditional_logic_table .exprdawc_label{display:block;margin-bottom:5px;font-weight:bold}.exprdawc_conditional_logic_table .exprdawc_input{width:100%;padding:5px;border:1px solid #ccc;border-radius:4px;box-sizing:border-box}.exprdawc_conditional_logic_table .exprdawc_checkbox{width:auto}.exprdawc_conditional_logic_table .exprdawc_textarea{width:100%;padding:8px;border:1px solid #ccc;border-radius:4px}.exprdawc_conditional_logic_table .exprdawc_no_entry_message{color:#a00;font-weight:bold}.exprdawc_conditional_logic_table h2{text-align:left;text-transform:uppercase}.exprdawc_conditional_logic_table .exprdawc_rule_group{margin-bottom:10px;padding:10px;border:1px solid #ddd;background-color:#f9f9f9;border-radius:4px}.exprdawc_conditional_logic_table .exprdawc_rule_group .exprdawc_rule{display:flex;align-items:center;margin-bottom:10px}.exprdawc_conditional_logic_table .exprdawc_rule_group .exprdawc_rule .exprdawc_input{margin-right:10px}.exprdawc_conditional_logic_table .exprdawc_rule_group .exprdawc_rule .button{margin-left:10px}.exprdawc_conditional_logic_table .exprdawc_rule_group .add_rule_group{margin-top:10px}.exprdawc_no_entry_message{padding-top:75px;margin:10px 0 0;position:relative;text-align:center;display:block;padding-bottom:1em;background:#fafafa;color:#5b5b5b;border:1px solid #c3c4c7;border-bottom:none}.exprdawc_no_entry_message::before{font-family:"Dashicons";content:"";font-size:70px;color:#6c6c6c;position:absolute;top:0px;left:50%;-ms-transform:translateX(-50%);transform:translateX(-50%)}a.exprdawc-export,a.exprdawc-import{text-decoration:underline dotted;font-size:small;color:#0073aa;margin:0 5px}a.exprdawc-export::before,a.exprdawc-import::before{font-family:"Dashicons";margin-right:5px;position:relative}a.exprdawc-export:hover,a.exprdawc-import:hover{color:#005a87;text-decoration:underline dotted}a.exprdawc-export::before{content:""}a.exprdawc-import::before{content:""}tr.exprdawc-validation-error{background-color:#fee !important;box-shadow:inset 0 0 0 1px red !important}tr.exprdawc-validation-error .exprdawc_fields_table{border:1px solid red}input.exprdawc-invalid-field{border-color:#d63638 !important;background-color:#ffe8e8 !important;box-shadow:inset 0 0 0 1px #d63638 !important}input.exprdawc-invalid-field:focus{border-color:#d63638 !important;background-color:#fff !important;box-shadow:0 0 0 3px rgba(214,54,56,.1) !important}.exprdawc-validation-error:first-of-type{animation:pulse-error .5s ease-in-out 2}@keyframes pulse-error{0%,100%{background-color:#fee}50%{background-color:#fcc}}/*# sourceMappingURL=admin-backend.css.map */
  • extra-product-data-for-woocommerce/trunk/assets/css/forms.css

    r3213497 r3469202  
    1 .exprdawc-label{display:block;font-weight:700}.exprdawc-field-input-yes-no,.exprdawc-field-wrapper-yes-no select,.exprdawc-input-wrapper .input-text{margin:2px 0 0;max-width:none;padding:5px;vertical-align:middle;width:100%}.exprdawc-field-input-yes-no,.exprdawc-field-wrapper-yes-no select{text-overflow:ellipsis}.exprdawc-description{font-size:smaller;font-style:italic}.exprdawc-field-wrapper{margin-bottom:15px}
     1.exprdawc-label{font-weight:bold;display:block}.exprdawc-input-wrapper .input-text{width:100%;max-width:none;padding:5px;vertical-align:middle;margin:2px 0 0}.exprdawc-field-input-yes-no,.exprdawc-field-wrapper-yes-no select{width:100%;max-width:none;padding:5px;vertical-align:middle;margin:2px 0 0;text-overflow:ellipsis}.exprdawc-description{font-style:italic;font-size:smaller}.exprdawc-field-wrapper{margin-bottom:15px}/*# sourceMappingURL=forms.css.map */
  • extra-product-data-for-woocommerce/trunk/assets/css/order-frontend.css

    r3206929 r3469202  
    1 .exprdawc-order-item-fields{background-color:#f9f9f9;border:1px solid #ddd;border-radius:4px;box-shadow:0 2px 4px rgba(0,0,0,.1);margin-top:10px;padding:15px}.exprdawc-order-item-fields .exprdawc-input{border:1px solid #ccc;border-radius:4px;box-sizing:border-box;margin-bottom:10px;padding:10px}.exprdawc-order-item-fields button{width:100%}
     1.exprdawc-order-item-fields{background-color:#f9f9f9;border:1px solid #ddd;border-radius:4px;padding:15px;margin-top:10px;box-shadow:0 2px 4px rgba(0,0,0,.1)}.exprdawc-order-item-fields .exprdawc-input{padding:10px;margin-bottom:10px;border:1px solid #ccc;border-radius:4px;box-sizing:border-box}.exprdawc-order-item-fields button{width:100%}/*# sourceMappingURL=order-frontend.css.map */
  • extra-product-data-for-woocommerce/trunk/extra-product-data-for-woocommerce.php

    r3460992 r3469202  
    33 * Plugin Name: Extra Product Data for WooCommerce
    44 * Description: Adds customizable input fields per product in WooCommerce, allowing users to enter extra details on the frontend .
    5  * Version: 1.8.2
     5 * Version: 2.0.1
    66 * Author: Triopsi
    77 * Author URI: https:// triopsi.dev
    88 * License: GPLv2 or later
    99 * License URI: https:// www.gnu.org/licenses/gpl-2.0.html
    10  * Text Domain: extra - product - data - for - woocommerce
     10 * Text Domain: extra-product-data-for-woocommerce
    1111 * WC requires at least: 3.9
    1212 * WC tested up to: 9.4
    1313 * Requires Plugins: woocommerce
     14 * Requires PHP: 8.0
     15 * Requires at least: 6.0
    1416 *
    1517 * @package ExtraProductDataForWooCommerce
    1618 */
    17 
    18 use function Triopsi\Exprdawc\tr_is_woocommerce_active;
    19 use Triopsi\Exprdawc\Exprdawc_Main;
    2019
    2120if ( ! defined( 'ABSPATH' ) ) {
     
    2322}
    2423
     24use Automattic\WooCommerce\Utilities\FeaturesUtil;
     25use Triopsi\Exprdawc\Exprdawc_Main;
     26
     27// Load Composer autoloader when available.
     28$autoload_path = __DIR__ . '/vendor/autoload.php';
     29if ( file_exists( $autoload_path ) ) {
     30    require_once $autoload_path;
     31}
     32
    2533// Include constants.
    2634require_once __DIR__ . '/src/constants.php';
    2735
    28 // Include functions/helpers.
    29 require_once EXPRDAWC_SRC . 'functions.php';
    30 
    31 // Include Base Order Class.
    32 require_once EXPRDAWC_CLASSES . 'class-exprdawc-base-order-class.php';
    33 
    34 // Include main class.
    35 require_once EXPRDAWC_CLASSES . 'class-exprdawc-main.php';
    36 
    37 // Include Helper Class.
    38 require_once EXPRDAWC_CLASSES . 'class-exprdawc-helper.php';
    39 
    40 // Is WooCommerce active? Then not, display a notice.
    41 if ( ! tr_is_woocommerce_active() ) {
    42     add_action( 'admin_notices', 'exprdawc_admin_notice' );
    43 } else {
    44     // Initiate the main class.
    45     Exprdawc_Main::get_instance();
    46 }
     36// Initiate the main class.
     37Exprdawc_Main::get_instance();
    4738
    4839// Declare compatibility with WooCommerce HPOS.
     
    5041    'before_woocommerce_init',
    5142    function () {
    52         if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) {
    53             \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', __FILE__, true );
    54 
     43        if ( class_exists( FeaturesUtil::class ) ) {
     44            FeaturesUtil::declare_compatibility( 'custom_order_tables', __FILE__, true );
    5545        }
    5646    }
     
    6757    <?php
    6858}
     59
     60/**
     61 * Deactivate the plugin if the PHP version is below 8.0.
     62 */
     63register_activation_hook(
     64    __FILE__,
     65    function () {
     66        if ( version_compare( PHP_VERSION, '8.0.0', '<' ) ) {
     67            deactivate_plugins( plugin_basename( __FILE__ ) );
     68            wp_die(
     69                esc_html__( 'This plugin requires PHP 8.0 or higher.', 'extra-product-data-for-woocommerce' ),
     70                esc_html__( 'Plugin Activation Error', 'extra-product-data-for-woocommerce' ),
     71                array( 'back_link' => true )
     72            );
     73        }
     74    }
     75);
  • extra-product-data-for-woocommerce/trunk/readme.txt

    r3461001 r3469202  
    55Tested up to: 6.7
    66Requires PHP: 8.2
    7 Stable tag: 1.8.2
     7Stable tag: 2.0.1
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    49492. Activate the plugin through the 'Plugins' screen in WordPress.
    50503. Go to any WooCommerce product page to see the additional input fields.
     51
     52== Development ==
     53
     54This plugin uses Composer autoloading for its PHP classes.
     55
     561. Run `composer install` in the plugin directory.
    5157
    5258== Frequently Asked Questions ==
     
    167173= 1.8.2 (13.02.2026) =
    168174* Fix: Required input name with full stops
     175
     176= 2.0.0 (25.02.2026) =
     177* various bug fixes in calculation, display, and when adding fields
     178* fixed default selection issues for select, checkbox, and radio
     179* added E2E tests with Playwright
     180* added WP ENV for development
     181* achieved >90% path coverage in PHPUnit
     182* fix for checking whether WooCommerce has already loaded
     183* stricter checks for usage of actions and filters
     184
     185= 2.0.1 (25.02.2026) =
     186* Fix and Bump Version to wg.org
  • extra-product-data-for-woocommerce/trunk/src/assets/js/wc-meta-boxes-product.js

    r3460848 r3469202  
    4343            this.bindEvents();
    4444            this.noEntryContent();
     45            this.bindFormValidation();
    4546        }
    4647
     
    5758            $(document).on('click', '.add_option', this.addOption.bind(this));
    5859            $(document).on('click', '.remove_option', this.removeOption.bind(this));
    59             $(document).on('click', 'a.exprdawc-export', this.exportContent.bind(this));
    60             $(document).on('click', 'a.exprdawc-import', this.importContent.bind(this));
    6160            $(document).on('change', '.exprdawc_input', this.setDirty.bind(this));
    6261            $(document).on('change', '.exprdawc_autocomplete_field', this.checkAutocompleteField.bind(this));
     
    340339                                </table>
    341340
    342                                 <!-- Text Option/Settings for radio, checkboxes and slects -->
     341                                <!-- Text Option/Settings for radio, checkboxes and selects -->
    343342                                <table class="exprdawc_settings_table exprdawc_text_table" style="display:none;">
    344343                                    <tbody>
     
    423422            this.setDirty();
    424423            const $row = $(e.currentTarget).closest('tr');
     424            const $type = $(e.currentTarget).val();
    425425            const $optionsRow = $row.next('.exprdawc_options');
    426426            const $optionsTable = $optionsRow.find('.exprdawc_options_table');
    427427            const $placeholderText = $optionsRow.find('.exprdawc_placeholder');
    428428
    429             if ($(e.currentTarget).val() === 'radio' || $(e.currentTarget).val() === 'checkbox') {
     429            if ($type === 'radio' || $type === 'checkbox' || $type === 'select') {
    430430                $placeholderText.prop('disabled', true);
    431431                $optionsTable.show();
     
    628628         * @returns
    629629         */
    630         exportContent(e) {
    631             e.preventDefault();
    632             // Update all field indices
    633             this.updateFieldIndices();
    634             if (this.isDirty) {
    635                 alert(`${exprdawc_admin_meta_boxes.pleaseSaveBeforeExportMsg}`);
    636                 return;
    637             }
    638             const $exportString = $('#exprdawc_export_string');
    639             const exportContent = $exportString.val();
    640             if (!exportContent) {
    641                 alert(`${exprdawc_admin_meta_boxes.emptyExportMsg}`);
    642                 return;
    643             }
    644             navigator.clipboard.writeText(exportContent).then(function () {
    645                 alert(`${exprdawc_admin_meta_boxes.copySuccessMsg}`);
    646             }, function (err) {
    647                 console.error('Could not copy text: ', err);
    648                 alert(`${exprdawc_admin_meta_boxes.copyErrorMsg}`);
    649             });
    650         }
    651 
    652         /**
    653          * Import content.
    654          * @param {*} e
    655          * @returns
    656          */
    657         importContent(e) {
    658             e.preventDefault();
    659             const exportString = prompt(exprdawc_admin_meta_boxes.enterExportString);
    660             if (exportString) {
    661                 const sureImportQuestion = confirm(exprdawc_admin_meta_boxes.sureImportQuestion);
    662                 if (!sureImportQuestion) {
    663                     return;
    664                 }
    665                 const productId = $('#post_ID').val();
    666                 $.ajax({
    667                     url: ajaxurl,
    668                     method: 'POST',
    669                     data: {
    670                         action: 'exprdawc_import_custom_fields',
    671                         product_id: productId,
    672                         export_string: exportString,
    673                         security: exprdawc_admin_meta_boxes.edit_exprdawc_nonce
    674                     },
    675                     success: function (response) {
    676                         if (response.success) {
    677                             alert(exprdawc_admin_meta_boxes.importSuccessMsg);
    678                             location.reload();
    679                         } else {
    680                             alert(exprdawc_admin_meta_boxes.importErrorMsg);
    681                         }
    682                     },
    683                     error: function () {
    684                         alert(exprdawc_admin_meta_boxes.importErrorMsg);
    685                     },
    686                 });
    687             }
    688         }
    689 
    690630        /**
    691631         * Set dirty.
     
    1013953                    $input.find('option:last').prop('selected', true);
    1014954                }
    1015             });
     955
     956                // Remove validation error classes
     957                $input.removeClass('exprdawc-invalid-field');
     958            });
     959
     960            // Remove validation error class from the row
     961            $clone.removeClass('exprdawc-validation-error');
    1016962
    1017963            // Append the cloned row to the table
     
    10661012        }
    10671013
     1014        /**
     1015         * Bindet das Form-Validierungs-Event zur WordPress Post-Form.
     1016         * Prüft, ob alle exprdawc_attributes einen gefüllten Label haben, bevor gespeichert wird.
     1017         */
     1018        bindFormValidation() {
     1019            // Prüfe Form-Submit auf der WordPress Post-Edit-Seite
     1020            $('#post').on('submit', (e) => {
     1021                if (!this.validateFields()) {
     1022                    e.preventDefault();
     1023                    e.stopPropagation();
     1024                    return false;
     1025                }
     1026            });
     1027
     1028            // Prüfe auch auf Schnellspeicher-Button und Veröffentlichungs-Buttons
     1029            $('#publish, #save-post').on('click', (e) => {
     1030                if (!this.validateFields()) {
     1031                    e.preventDefault();
     1032                    e.stopPropagation();
     1033                    return false;
     1034                }
     1035            });
     1036        }
     1037
     1038        /**
     1039         * Validiert alle exprdawc_attributes.
     1040         * Prüft, dass jedes Feld einen non-empty Label hat.
     1041         *
     1042         * @returns {boolean} true wenn Validierung erfolgreich, false wenn Fehler
     1043         */
     1044        validateFields() {
     1045            const $fields = $('#exprdawc_field_body').find('tr.exprdawc_fields_wrapper');
     1046
     1047            if ($fields.length === 0) {
     1048                // Keine Felder vorhanden - das ist ok
     1049                return true;
     1050            }
     1051
     1052            let hasErrors = false;
     1053            const errorFields = [];
     1054
     1055            $fields.each((index, element) => {
     1056                const $row = $(element);
     1057                const $labelInput = $row.find('input.exprdawc_label');
     1058                const labelValue = $labelInput.val().trim();
     1059
     1060                if (labelValue === '') {
     1061                    hasErrors = true;
     1062                    errorFields.push(index + 1); // 1-basiert für Benutzerlesbarkeit
     1063
     1064                    // Visuell markieren des fehlerhaften Feldes
     1065                    $row.addClass('exprdawc-validation-error');
     1066                    $labelInput.addClass('exprdawc-invalid-field');
     1067                } else {
     1068                    // Fehlermarkierung entfernen wenn Feld ok ist
     1069                    $row.removeClass('exprdawc-validation-error');
     1070                    $labelInput.removeClass('exprdawc-invalid-field');
     1071                }
     1072            });
     1073
     1074            if (hasErrors) {
     1075                const fieldCount = errorFields.length;
     1076                const fieldNumbersText = errorFields.join(', ');
     1077                const hasMultipleErrors = fieldCount > 1;
     1078                console.log(exprdawc_admin_meta_boxes.validation_warning)
     1079                const warningMessage = exprdawc_admin_meta_boxes.validation_warning;
     1080                alert(warningMessage);
     1081                return false;
     1082            }
     1083
     1084            return true;
     1085        }
     1086
    10681087    }
    10691088
  • extra-product-data-for-woocommerce/trunk/src/assets/js/wc-product-frontend.js

    r3460848 r3469202  
    198198
    199199                    let fieldPrice = 0;
     200                    let adjustmentType = 'fixed';
    200201                    if (fieldType === "select") {
    201202                        const $selectedOption = $(this).find("option:selected");
    202203                        if ($selectedOption.data('price-adjustment')) {
    203204                            fieldPrice = parseFloat($selectedOption.data('price-adjustment')) || 0;
     205                            adjustmentType = $selectedOption.data('price-adjustment-type') || 'fixed';
    204206                        }
    205207                    } else {
    206208                        fieldPrice = parseFloat($(this).data('price-adjustment')) || 0;
     209                        adjustmentType = $(this).data('price-adjustment-type') || 'fixed';
     210                    }
     211
     212                    // Calculate percentage-based price adjustments
     213                    if (adjustmentType === 'percentage' && fieldPrice !== 0) {
     214                        fieldPrice = (basePrice * fieldPrice) / 100;
    207215                    }
    208216
  • extra-product-data-for-woocommerce/trunk/src/assets/scss/admin-backend.scss

    r3460848 r3469202  
    423423    content: "\f342";
    424424}
     425
     426/**
     427 * Validation Error Styles
     428 * Markiert Felder mit Validierungsfehlern
     429 */
     430tr.exprdawc-validation-error {
     431    background-color: #fee !important;
     432    box-shadow: inset 0 0 0 1px #f00 !important;
     433   
     434    .exprdawc_fields_table {
     435        border: 1px solid #f00;
     436    }
     437}
     438
     439input.exprdawc-invalid-field {
     440    border-color: #d63638 !important;
     441    background-color: #ffe8e8 !important;
     442    box-shadow: inset 0 0 0 1px #d63638 !important;
     443   
     444    &:focus {
     445        border-color: #d63638 !important;
     446        background-color: #fff !important;
     447        box-shadow: 0 0 0 3px rgba(214, 54, 56, 0.1) !important;
     448    }
     449}
     450
     451/**
     452 * Scrolle zum ersten Fehler bei Validierung
     453 * Hilft dem Nutzer das Problem schnell zu finden
     454 */
     455.exprdawc-validation-error:first-of-type {
     456    animation: pulse-error 0.5s ease-in-out 2;
     457}
     458
     459@keyframes pulse-error {
     460    0%, 100% {
     461        background-color: #fee;
     462    }
     463    50% {
     464        background-color: #ffcccc;
     465    }
     466}
  • extra-product-data-for-woocommerce/trunk/src/classes/class-exprdawc-main.php

    r3221376 r3469202  
    2525 */
    2626
     27declare( strict_types=1 );
    2728namespace Triopsi\Exprdawc;
    2829
     
    3031    exit; // Exit if accessed directly.
    3132}
    32 use function Triopsi\Exprdawc\tr_is_woocommerce_active;
     33use Triopsi\Exprdawc\Helper\Exprdawc_Helper;
     34use Triopsi\Exprdawc\Order\Admin\Exprdawc_Admin_Order;
     35use Triopsi\Exprdawc\Order\Customer\Exprdawc_User_Order;
    3336
    3437/**
     
    5760
    5861    /**
    59      * Product Fronted Object Holder.
     62     * Product Frontend Object Holder.
    6063     *
    61      * @var \Product_Page_Fronted
     64     * @var \Product_Page_Frontend
    6265     */
    63     protected $exprdawc_product_fronted = null;
     66    protected $exprdawc_product_frontend = null;
    6467
    6568    /**
     
    7881
    7982    /**
     83     * User Order Object Holder.
     84     *
     85     * @var \User_Order
     86     */
     87    protected $exprdawc_user_order = null;
     88
     89    /**
    8090     * Creates or returns an instance of this class.
    8191     *
     
    90100
    91101    /**
    92      * Register the autoloader.
    93      */
    94     protected function register_autoloader() {
    95         require_once EXPRDAWC_CLASSES . 'class-autoloader.php';
    96         Autoloader::setup( EXPRDAWC_CLASSES, __NAMESPACE__ );
    97     }
    98 
    99     /**
    100102     * Initiate our sub-objects.
    101103     */
    102104    protected function __construct() {
    103 
    104         $this->register_autoloader();
    105 
    106105        // Init Hooks.
    107106        add_action( 'init', array( $this, 'load_components' ), 0 );
     
    132131    public function load_components() {
    133132
    134         if ( tr_is_woocommerce_active() ) {
     133        if ( Exprdawc_Helper::is_woocommerce_active() ) {
    135134
    136135            // Product Create/Edit Page.
    137136            $this->exprdawc_product_backend = new Exprdawc_Product_Page_Backend();
    138137
    139             // Product Product Fronted.
    140             $this->exprdawc_product_fronted = new Exprdawc_Product_Page_Fronted();
     138            // Product Product Frontend.
     139            $this->exprdawc_product_frontend = new Exprdawc_Product_Page_Frontend();
    141140
    142141            // Admin Order Edit Page.
    143142            $this->exprdawc_admin_order_edit = new Exprdawc_Admin_Order();
    144143
    145             // Settings.
     144            // User Order.
     145            $this->exprdawc_user_order = new Exprdawc_User_Order();
     146
     147            // Add Settings in the WooCommerce Settings Page.
    146148            $this->exprdawc_settings = new Exprdawc_Settings();
    147 
    148             // User Order.
    149             new Exprdawc_User_Order();
    150 
    151149        }
    152150    }
     
    159157    public function exprdawc_only_admin_enqueue_scripts() {
    160158        if ( is_admin() ) {
    161             wp_enqueue_style( 'exprdawc-backend-css', EXPRDAWC_ASSETS_CSS . 'admin-backend.css', array(), '1.0.0', 'all' );
    162             wp_enqueue_style( 'form-css', EXPRDAWC_ASSETS_CSS . 'forms.css', array(), '1.0.0', 'all' );
     159            wp_enqueue_style( 'exprdawc-backend-css', EXPRDAWC_ASSETS_CSS . 'admin-backend.css', array(), EXPRDAWC_VERSION, 'all' );
     160            wp_enqueue_style( 'form-css', EXPRDAWC_ASSETS_CSS . 'forms.css', array(), EXPRDAWC_VERSION, 'all' );
    163161        }
    164162    }
  • extra-product-data-for-woocommerce/trunk/src/classes/class-exprdawc-product-page-backend.php

    r3460848 r3469202  
    2525 */
    2626
     27declare( strict_types=1 );
    2728namespace Triopsi\Exprdawc;
    2829
     
    3031    exit; // Exit if accessed directly.
    3132}
     33
     34use Triopsi\Exprdawc\Helper\Exprdawc_Helper;
     35
    3236/**
    33  * Class Selection
    34  *
    35  * This class represents a selection of items. It provides methods to add, remove,
    36  * and retrieve items from the selection. The selection can be manipulated and queried
     37 * Class Exprdawc_Product_Page_Backend
     38 *
     39 * This class represents the backend functionality for the product page in the Extra Product Data for WooCommerce plugin.
     40 * It provides methods to add, remove, and retrieve items from the selection. The selection can be manipulated and queried
    3741 * to perform various operations on the contained items.
    3842 *
     
    4751
    4852        // Add custom tab in product edit page.
    49         add_filter( 'woocommerce_product_data_tabs', array( $this, 'exprdawc_add_custom_product_tab' ) );
    50         add_action( 'woocommerce_product_data_panels', array( $this, 'exprdawc_add_custom_product_fields' ) );
    51 
    52         // Save custom fields.
    53         add_action( 'woocommerce_process_product_meta', array( $this, 'exprdawc_save_extra_product_fields' ) );
    54 
    55         // Add Scripts in head and footer.
    56         add_action( 'admin_enqueue_scripts', array( $this, 'exprdawc_show_general_tab' ) );
    57 
    58         // Import custom fields.
    59         add_action( 'wp_ajax_exprdawc_import_custom_fields', array( $this, 'exprdawc_import_custom_fields' ) );
     53        if ( is_admin() ) {
     54            add_filter( 'woocommerce_product_data_tabs', array( $this, 'exprdawc_add_custom_product_tab' ) );
     55            add_action( 'woocommerce_product_data_panels', array( $this, 'exprdawc_add_custom_product_fields' ) );
     56
     57            // Save custom fields.
     58            add_action( 'woocommerce_process_product_meta', array( $this, 'exprdawc_save_extra_product_fields' ) );
     59
     60            // Add Scripts in head and footer.
     61            add_action( 'admin_enqueue_scripts', array( $this, 'exprdawc_show_general_tab' ) );
     62
     63            // Import custom fields.
     64            add_action( 'wp_ajax_exprdawc_import_custom_fields', array( $this, 'exprdawc_import_custom_fields' ) );
     65        }
    6066    }
    6167
     
    7783
    7884    /**
    79      * Add custom fields to the product edit page.
    80      *
    81      * This function is responsible for adding custom fields to the product edit page
    82      * in the WooCommerce admin interface. It ensures that the fields are displayed
    83      * correctly and can be used to store additional product data.
    84      */
    85     public function exprdawc_add_custom_product_fields() {
     85     * Add custom product fields to the product edit page.
     86     *
     87     * This function is hooked to the 'woocommerce_product_data_panels' action and is responsible for
     88     * rendering the HTML for the custom product fields panel in the product edit page.
     89     */
     90    public function exprdawc_add_custom_product_fields(): void {
    8691        global $post;
    87         $product       = wc_get_product( $post );
     92        $post_id = ( $post instanceof \WP_Post ) ? (int) $post->ID : 0;
     93        if ( $post_id <= 0 ) {
     94            return;
     95        }
     96
     97        echo $this->get_custom_product_fields_panel_html( $post_id ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
     98    }
     99
     100    /**
     101     * Get the HTML for the custom product fields panel.
     102     *
     103     * @param int $product_id The ID of the product for which to get the panel HTML.
     104     * @return string The HTML for the custom product fields panel.
     105     */
     106    public function get_custom_product_fields_panel_html( int $product_id ): string {
     107        $product = wc_get_product( $product_id );
     108        if ( ! $product ) {
     109            return '';
     110        }
     111
    88112        $custom_fields = $product->get_meta( '_extra_product_fields', true );
    89         include EXPRDAWC_TEMPLATES . 'html-tab-extra-attributes.php';
     113        if ( ! is_array( $custom_fields ) ) {
     114            $custom_fields = array();
     115        }
     116
     117        ob_start();
     118        Exprdawc_Helper::render_template(
     119            'html-tab-extra-attributes.php',
     120            array(
     121                'product'       => $product,
     122                'custom_fields' => $custom_fields,
     123                'product_id'    => $product_id,
     124            )
     125        );
     126        return (string) ob_get_clean();
    90127    }
    91128
     
    96133     */
    97134    public function exprdawc_show_general_tab() {
    98         wp_enqueue_script( 'exprdawc-wc-meta-boxes-js', EXPRDAWC_ASSETS_JS . 'wc-meta-boxes-product.js', array( 'jquery', 'jquery-ui-sortable' ), '1.0.0', true );
     135        // Enqueue main product meta boxes script.
     136        wp_enqueue_script( 'exprdawc-wc-meta-boxes-js', EXPRDAWC_ASSETS_JS . 'wc-meta-boxes-product.min.js', array( 'jquery', 'jquery-ui-sortable' ), EXPRDAWC_VERSION, true );
     137
     138        // Enqueue import/export modal CSS and JS.
     139        wp_enqueue_style( 'exprdawc-import-export-modal-css', EXPRDAWC_ASSETS_CSS . 'import-export-modal.css', array(), EXPRDAWC_VERSION );
     140        wp_enqueue_script( 'exprdawc-import-export-modal-js', EXPRDAWC_ASSETS_JS . 'import-export-modal.min.js', array( 'jquery' ), EXPRDAWC_VERSION, true );
     141
    99142        wp_localize_script(
    100143            'exprdawc-wc-meta-boxes-js',
     
    103146                'edit_exprdawc_nonce'                  => wp_create_nonce( 'edit_exprdawc_nonce' ),
    104147                'label_placeholder'                    => esc_html__( 'Name of the label', 'extra-product-data-for-woocommerce' ),
     148                'columns'                              => esc_html__( 'Columns', 'extra-product-data-for-woocommerce' ),
    105149                'short_text'                           => esc_html__( 'Short Text', 'extra-product-data-for-woocommerce' ),
    106150                'long_text'                            => esc_html__( 'Long Text', 'extra-product-data-for-woocommerce' ),
     
    203247                'enable_price_adjustment'              => esc_html__( 'Enable price adjustment', 'extra-product-data-for-woocommerce' ),
    204248                'price_adjustment_type'                => esc_html__( 'Price Adjustment Type', 'extra-product-data-for-woocommerce' ),
     249                'validation_warning'                   => esc_html__( 'Warning! No label text (Labels) was found. Please fill all fields with label text before saving.', 'extra-product-data-for-woocommerce' ),
    205250                'price_adjustment_value'               => esc_html__( 'Price Adjustment Value', 'extra-product-data-for-woocommerce' ),
    206251                'fixed'                                => esc_html__( 'Fixed Price', 'extra-product-data-for-woocommerce' ),
     
    208253                'quantity'                             => esc_html__( 'Price per Quantity', 'extra-product-data-for-woocommerce' ),
    209254                'default_selected'                     => esc_html__( 'Default selected', 'extra-product-data-for-woocommerce' ),
     255                'exportTitle'                          => esc_html__( 'Export Custom Fields', 'extra-product-data-for-woocommerce' ),
     256                'importTitle'                          => esc_html__( 'Import Custom Fields', 'extra-product-data-for-woocommerce' ),
     257                'invalidJsonMsg'                       => esc_html__( 'Invalid JSON format. Please check your input.', 'extra-product-data-for-woocommerce' ),
     258                'importingMsg'                         => esc_html__( 'Importing...', 'extra-product-data-for-woocommerce' ),
    210259            )
    211260        );
     
    333382            // Save the custom fields to the product.
    334383            $product->update_meta_data( '_extra_product_fields', $custom_fields );
    335 
    336384        } else {
    337385            // Get the product.
     
    340388            // Delete the custom fields from the product.
    341389            $product->delete_meta_data( '_extra_product_fields' );
    342 
    343390        }
    344391
  • extra-product-data-for-woocommerce/trunk/src/classes/class-exprdawc-settings.php

    r3460848 r3469202  
    2525 */
    2626
     27declare( strict_types=1 );
    2728namespace Triopsi\Exprdawc;
    2829
     
    111112                array(
    112113                    'title'   => __( 'Custom Add to CartText', 'extra-product-data-for-woocommerce' ),
    113                     'desc'    => __( 'Enter custom text for the "Add to cart" button if the product has extra product data fields. If not specified, the WooCommerce default will be used.', 'extra-product-data-for-woocommerce' ),
     114                    'desc'    => __( 'Enter custom text for the "Add to cart" button if the product has extra product data fields.', 'extra-product-data-for-woocommerce' ),
    114115                    'id'      => 'exprdawc_custom_add_to_cart_text',
    115                     'default' => '',
     116                    'default' => __( 'Configure Product', 'extra-product-data-for-woocommerce' ),
    116117                    'type'    => 'text',
    117118                ),
  • extra-product-data-for-woocommerce/trunk/src/constants.php

    r3460848 r3469202  
    3030
    3131// Useful global constants.
    32 $version = '1.8.0';
     32$version = '2.0.1';
    3333define( 'EXPRDAWC_VERSION', $version );
    3434define( 'EXPRDAWC_PLUGIN_MAIN_FILE', 'extra-product-data-for-woocommerce.php' );
  • extra-product-data-for-woocommerce/trunk/src/templates/view/fields/checkbox.php

    r3460848 r3469202  
    11<?php
    22/**
    3  * Created on Tue Nov 26 2024
     3 * Checkbox Field Template (Template Engine Version)
    44 *
    5  * Copyright (c) 2024 IT-Dienstleistungen Drevermann - All Rights Reserved
     5 * Variables available:
     6 * - $field: Complete field configuration
     7 * - $required_string: Required indicator HTML
     8 * - $custom_attributes: Array of custom HTML attributes
    69 *
    7  * @package Extra Product Data for WooCommerce
    8  * @author Daniel Drevermann <info@triopsi.com>
    9  * @copyright Copyright (c) 2024, IT-Dienstleistungen Drevermann
    10  *
    11  * This program is free software: you can redistribute it and/or modify
    12  * it under the terms of the GNU General Public License as published by
    13  * the Free Software Foundation, either version 2 of the License, or
    14  * (at your option) any later version.
    15  *
    16  * This program is distributed in the hope that it will be useful,
    17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    19  * GNU General Public License for more details.
    20  *
    21  * You should have received a copy of the GNU General Public License
    22  * along with this program. If not, see <https://www.gnu.org/licenses/>.
    23  *
    24  * This file is part of the development of WordPress plugins.
     10 * @package Extra_Product_Data_For_WooCommerce\Helper
     11 * @since 1.9.0
    2512 */
     13
     14use Triopsi\Exprdawc\Helper\Exprdawc_Template_Helpers as H;
     15
    2616// phpcs:ignoreFile
    2717if ( ! defined( 'ABSPATH' ) ) {
    2818    exit;
    2919}
    30 echo '<label class="' . esc_attr( implode( ' ', $field_args['label_class'] ) ) . '">' . esc_html( $field_args['label'] ) . $required_string . '</label>';
    31 echo '<span class="' . esc_attr( implode( ' ', $field_args['input_wrapper_class'] ) ) . '">';
    32 if ( isset( $field_args['options'] ) && is_array( $field_args['options'] ) ) {
    33     foreach ( $field_args['options'] as $option ) {
    34         $option_value = $option['value'];
    35         $option_label = $option['label'];
    36         $checked      = in_array( $option_value, (array) explode( ', ', $field_args['value'] ) ) ? 'checked' : '';
    37         $id           = $field_args['id'] . '-' . str_replace( array( ' ', '_' ), '-', $option_value );
    3820
    39         // if option have adjustable price than add price to the label.
    40         $price_adjustment = array();
    41         if ( isset( $option['price_adjustment_value'] ) && $field_args['adjust_price'] ) {
    42             $plus_minus    = $option['price_adjustment_value'] != 0 ? ( $option['price_adjustment_value'] > 0 ? '+' : '-' ) : '';
    43             $option_label .= ' (' . $plus_minus . wc_price( $option['price_adjustment_value'] ) . ')';
    44             // Add custom data attribute to the input field and type.
    45             $price_adjustment[] = 'data-price-adjustment="' . esc_attr( $option['price_adjustment_value'] ) . '"';
    46             $price_adjustment[] = 'data-price-adjustment-type="' . esc_attr( $option['price_adjustment_type'] ) . '"';
    47             // add data label to the input field.
    48             $price_adjustment[] = 'data-label="' . esc_attr( $option_label ) . '"';
    49         }
     21// Alias field_args as field for template.
     22$field = $field_args ?? array();
     23?>
    5024
    51         echo '<div class="exprdawc-checkbox-option">';
    52         echo '<input type="checkbox"
    53             id="' . esc_attr( $id ) . '"
    54             name="' . esc_attr( $field_args['name'] ) . '[]"
    55             value="' . esc_attr( $option_value ) . '"
    56             ' . $checked . '
    57             class="' . esc_attr( implode( ' ', $field_args['input_class'] ) ) . '"
    58             ' . implode( ' ', $custom_attributes ) . '
    59             ' . implode( ' ', $price_adjustment ) . '/>';
     25<label class="<?php echo H::classes( $field['label_class'] ); ?>">
     26    <?php echo H::e( $field['label'] ); ?>
     27    <?php echo $required_string; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
     28</label>
    6029
    61         echo '<label for="' . esc_attr( $id ) . '" class="exprdawc-label-checkbox">' . $option_label . '</label>';
    62         echo '</div>';
    63     }
    64     if ( isset( $field_args['unchecked_value'] ) ) {
    65         echo '<input type="hidden" name="' . esc_attr( $field_args['id'] ) . '[]" value="' . esc_attr( $field_args['unchecked_value'] ) . '" />';
    66     }
    67 }
    68 echo '</span>';
    69 if ( ! empty( $field_args['description'] ) ) {
    70     echo '<span id="' . esc_attr( $field_args['id'] ) . '-description" class="' . esc_attr( implode( ' ', $field_args['description_class'] ) ) . '">' . esc_html( $field_args['description'] ) . '</span>';
    71 }
     30<span class="<?php echo H::classes( $field['input_wrapper_class'] ); ?>">
     31    <?php if ( ! empty( $field['options'] ) && is_array( $field['options'] ) ) : ?>
     32        <?php foreach ( $field['options'] as $option ) : ?>
     33            <?php
     34            $option_value = $option['value'] ?? '';
     35            $option_label = $option['label'] ?? '';
     36            $checked      = H::checked( $field['value'], $option_value );
     37            $option_id    = H::id( $field['id'] . '-' . $option_value );
    7238
    73 // Add the required checbox check with inline js code
    74 if ( $field_args['required'] ) {
    75     ?>
     39            // Build data attributes for price adjustment.
     40            $data_attrs = array();
     41            if ( ! empty( $option['price_adjustment_value'] ) ) {
     42                $data_attrs['price-adjustment']      = $option['price_adjustment_value'];
     43                $data_attrs['price-adjustment-type'] = $option['price_adjustment_type'] ?? 'fixed';
     44                $data_attrs['label']                 = $option_label;
     45            }
     46            ?>
     47
     48            <div class="exprdawc-checkbox-option">
     49                <input type="checkbox"
     50                    id="<?php echo H::attr( $option_id ); ?>"
     51                    name="<?php echo H::attr( $field['name'] ); ?>[]"
     52                    value="<?php echo H::attr( $option_value ); ?>"
     53                    <?php echo $checked; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
     54                    class="<?php echo H::classes( $field['input_class'] ); ?>"
     55                    <?php echo H::join( $custom_attributes ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
     56                    <?php echo H::data_attrs( $data_attrs ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
     57                />
     58                <label for="<?php echo H::attr( $option_id ); ?>" class="exprdawc-label-checkbox">
     59                    <?php echo H::e( $option_label ); ?>
     60                </label>
     61            </div>
     62
     63        <?php endforeach; ?>
     64
     65        <?php if ( isset( $field['unchecked_value'] ) ) : ?>
     66            <input type="hidden"
     67                name="<?php echo H::attr( $field['id'] ); ?>[]"
     68                value="<?php echo H::attr( $field['unchecked_value'] ); ?>"
     69            />
     70        <?php endif; ?>
     71    <?php endif; ?>
     72</span>
     73
     74<?php if ( ! empty( $field['description'] ) ) : ?>
     75    <span id="<?php echo H::attr( $field['id'] ); ?>-description"
     76        class="<?php echo H::classes( $field['description_class'] ); ?>">
     77        <?php echo H::e( $field['description'] ); ?>
     78    </span>
     79<?php endif; ?>
     80
     81<?php if ( ! empty( $field['required'] ) ) : ?>
    7682    <script>
    7783        jQuery(document).ready(function($) {
    78             const $checkboxGroups = $('.<?php echo esc_js( $field_args['id'] . '-input-wrapper' ); ?>, .exprdawc-field-input-wrapper-required');
     84            const $checkboxGroups = $('.<?php echo H::js( $field['id'] . '-input-wrapper' ); ?>, .exprdawc-field-input-wrapper-required');
    7985            $checkboxGroups.each(function () {
    8086                const $checkboxes = $(this).find('input[type="checkbox"]');
     
    8288                    const isChecked = $checkboxes.is(":checked");
    8389                    $checkboxes.prop("required", !isChecked);
    84                 }).trigger('change'); // Trigger change event on page load to set initial state
     90                }).trigger('change');
    8591            });
    8692        });
    8793    </script>
    88     <?php
    89 }
     94<?php endif; ?>
  • extra-product-data-for-woocommerce/trunk/src/templates/view/fields/radio.php

    r3460848 r3469202  
    11<?php
    22/**
    3  * Created on Tue Nov 26 2024
     3 * Radio Field Template (Template Engine Version)
    44 *
    5  * Copyright (c) 2024 IT-Dienstleistungen Drevermann - All Rights Reserved
     5 * Variables available:
     6 * - $field: Complete field configuration
     7 * - $required_string: Required indicator HTML
     8 * - $custom_attributes: Array of custom HTML attributes
    69 *
    7  * @package Extra Product Data for WooCommerce
    8  * @author Daniel Drevermann <info@triopsi.com>
    9  * @copyright Copyright (c) 2024, IT-Dienstleistungen Drevermann
    10  *
    11  * This program is free software: you can redistribute it and/or modify
    12  * it under the terms of the GNU General Public License as published by
    13  * the Free Software Foundation, either version 2 of the License, or
    14  * (at your option) any later version.
    15  *
    16  * This program is distributed in the hope that it will be useful,
    17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    19  * GNU General Public License for more details.
    20  *
    21  * You should have received a copy of the GNU General Public License
    22  * along with this program. If not, see <https://www.gnu.org/licenses/>.
    23  *
    24  * This file is part of the development of WordPress plugins.
     10 * @package Extra_Product_Data_For_WooCommerce
     11 * @since 1.9.0
    2512 */
     13
     14use Triopsi\Exprdawc\Helper\Exprdawc_Template_Helpers as H;
     15
    2616// phpcs:ignoreFile
    2717if ( ! defined( 'ABSPATH' ) ) {
    2818    exit;
    2919}
    30 echo '<label class="' . esc_attr( implode( ' ', $field_args['label_class'] ) ) . '">' . esc_html( $field_args['label'] ) . $required_string . '</label>';
    31 echo '<span class="' . esc_attr( implode( ' ', $field_args['input_wrapper_class'] ) ) . '">';
    32 if ( isset( $field_args['options'] ) && is_array( $field_args['options'] ) ) {
    33     foreach ( $field_args['options'] as $option ) {
    34         $option_value = $option['value'];
    35         $option_label = $option['label'];
    36         $checked      = in_array( $option_value, (array) $field_args['value'] ) ? 'checked' : '';
    37         $id           = $field_args['id'] . '-' . str_replace( array( ' ', '_' ), '-', $option_value );
    3820
    39         // if option have adjustable price than add price to the label.
    40         $price_adjustment = array();
    41         if ( isset( $option['price_adjustment_value'] ) && $field_args['adjust_price'] ) {
    42             $plus_minus    = $option['price_adjustment_value'] != 0 ? ( $option['price_adjustment_value'] > 0 ? '+' : '-' ) : '';
    43             $option_label .= ' (' . $plus_minus . wc_price( $option['price_adjustment_value'] ) . ')';
    44             // Add custom data attribute to the input field and type.
    45             $price_adjustment[] = 'data-price-adjustment="' . esc_attr( $option['price_adjustment_value'] ) . '"';
    46             $price_adjustment[] = 'data-price-adjustment-type="' . esc_attr( $option['price_adjustment_type'] ) . '"';
    47             // add data label to the input field.
    48             $price_adjustment[] = 'data-label="' . esc_attr( $option_label ) . '"';
    49         }
     21// Alias field_args as field for template.
     22$field = $field_args ?? array();
     23?>
    5024
    51         echo '<div class="exprdawc-checkbox-option">';
    52         echo '<input type="radio"
    53             id="' . esc_attr( $id ) . '"
    54             name="' . esc_attr( $field_args['name'] ) . '[]"
    55             value="' . esc_attr( $option_value ) . '"
    56             ' . $checked . '
    57             class="' . esc_attr( implode( ' ', $field_args['input_class'] ) ) . '"
    58             ' . implode( ' ', $custom_attributes ) . '
    59             ' . implode( ' ', $price_adjustment ) . '/>';
     25<label class="<?php echo H::classes( $field['label_class'] ); ?>">
     26    <?php echo H::e( $field['label'] ); ?>
     27    <?php echo $required_string; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
     28</label>
    6029
    61         echo '<label for="' . esc_attr( $id ) . '" class="exprdawc-label-checkbox">' . $option_label . '</label>';
    62         echo '</div>';
    63     }
    64 }
    65 echo '</span>';
    66 if ( ! empty( $field_args['description'] ) ) {
    67     echo '<span id="' . esc_attr( $field_args['id'] ) . '-description" class="' . esc_attr( implode( ' ', $field_args['description_class'] ) ) . '">' . esc_html( $field_args['description'] ) . '</span>';
    68 }
     30<span class="<?php echo H::classes( $field['input_wrapper_class'] ); ?>">
     31    <?php if ( ! empty( $field['options'] ) && is_array( $field['options'] ) ) : ?>
     32        <?php foreach ( $field['options'] as $option ) : ?>
     33            <?php
     34            $option_value = $option['value'] ?? '';
     35            $option_label = $option['label'] ?? '';
     36            $checked      = H::checked( $field['value'] ?? '', $option_value );
     37            $option_id    = H::id( $field['id'] . '-' . $option_value );
     38
     39            // Build data attributes for price adjustment.
     40            $data_attrs = array();
     41            if ( ! empty( $option['price_adjustment_value'] ) ) {
     42                $data_attrs['price-adjustment']      = $option['price_adjustment_value'];
     43                $data_attrs['price-adjustment-type'] = $option['price_adjustment_type'] ?? 'fixed';
     44                $data_attrs['label']                 = $option_label;
     45            }
     46            ?>
     47
     48            <div class="exprdawc-radio-option">
     49                <input type="radio"
     50                    id="<?php echo H::attr( $option_id ); ?>"
     51                    name="<?php echo H::attr( $field['name'] ); ?>"
     52                    value="<?php echo H::attr( $option_value ); ?>"
     53                    <?php echo $checked; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
     54                    class="<?php echo H::classes( $field['input_class'] ); ?>"
     55                    <?php echo H::join( $custom_attributes ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
     56                    <?php echo H::data_attrs( $data_attrs ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
     57                />
     58                <label for="<?php echo H::attr( $option_id ); ?>" class="exprdawc-label-radio">
     59                    <?php echo H::e( $option_label ); ?>
     60                </label>
     61            </div>
     62
     63        <?php endforeach; ?>
     64    <?php endif; ?>
     65</span>
     66
     67<?php if ( ! empty( $field['description'] ) ) : ?>
     68    <span id="<?php echo H::attr( $field['id'] ); ?>-description"
     69        class="<?php echo H::classes( $field['description_class'] ); ?>">
     70        <?php echo H::e( $field['description'] ); ?>
     71    </span>
     72<?php endif; ?>
  • extra-product-data-for-woocommerce/trunk/src/templates/view/fields/select.php

    r3460848 r3469202  
    11<?php
    22/**
    3  * Created on Tue Nov 26 2024
     3 * Select Field Template (Template Engine Version)
    44 *
    5  * Copyright (c) 2024 IT-Dienstleistungen Drevermann - All Rights Reserved
     5 * Variables available:
     6 * - $field: Complete field configuration
     7 * - $required_string: Required indicator HTML
     8 * - $custom_attributes: Array of custom HTML attributes
    69 *
    7  * @package Extra Product Data for WooCommerce
    8  * @author Daniel Drevermann <info@triopsi.com>
    9  * @copyright Copyright (c) 2024, IT-Dienstleistungen Drevermann
    10  *
    11  * This program is free software: you can redistribute it and/or modify
    12  * it under the terms of the GNU General Public License as published by
    13  * the Free Software Foundation, either version 2 of the License, or
    14  * (at your option) any later version.
    15  *
    16  * This program is distributed in the hope that it will be useful,
    17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    19  * GNU General Public License for more details.
    20  *
    21  * You should have received a copy of the GNU General Public License
    22  * along with this program. If not, see <https://www.gnu.org/licenses/>.
    23  *
    24  * This file is part of the development of WordPress plugins.
     10 * @package Extra_Product_Data_For_WooCommerce
     11 * @since 1.9.0
    2512 */
     13
     14use Triopsi\Exprdawc\Helper\Exprdawc_Template_Helpers as H;
     15
    2616// phpcs:ignoreFile
    2717if ( ! defined( 'ABSPATH' ) ) {
    2818    exit;
    2919}
    30 echo '<label for="' . esc_attr( $field_args['id'] ) . '" class="' . esc_attr( implode( ' ', $field_args['label_class'] ) ) . '">' . esc_html( $field_args['label'] ) . $required_string . '</label>';
    31 echo '<span class="' . esc_attr( implode( ' ', $field_args['input_wrapper_class'] ) ) . '">';
    32 if ( isset( $field_args['options'] ) && is_array( $field_args['options'] ) ) {
    33     echo '<select class="select ' . esc_attr( implode( ' ', $field_args['input_class'] ) ) . '"
    34     id="' . esc_attr( $field_args['id'] ) . '"
    35     name="' . esc_attr( $field_args['name'] ) . '"
    36     ' . implode( ' ', $custom_attributes ) . '>';
    3720
    38     // If placeholder is set, add it as an option.
    39     if ( ! empty( $field_args['placeholder'] ) ) {
    40         echo '<option value="" disabled selected>' . esc_html( $field_args['placeholder'] ) . '</option>';
    41     }
    42     foreach ( $field_args['options'] as $option ) {
    43         $option_value = $option['value'];
    44         $option_label = $option['label'];
    45         $selected     = selected( $field_args['value'], $option_value, false );
    46         // if option have adjustable price than add price to the label.
    47         $price_adjustment = array();
    48         if ( isset( $option['price_adjustment_value'] ) && $field_args['adjust_price'] ) {
    49             $plus_minus    = $option['price_adjustment_value'] != 0 ? ( $option['price_adjustment_value'] > 0 ? '+' : '-' ) : '';
    50             $option_label .= ' (' . $plus_minus . wc_price( $option['price_adjustment_value'] ) . ')';
    51             // Add custom data attribute to the input field and type.
    52             $price_adjustment[] = 'data-price-adjustment="' . esc_attr( $option['price_adjustment_value'] ) . '"';
    53             $price_adjustment[] = 'data-price-adjustment-type="' . esc_attr( $option['price_adjustment_type'] ) . '"';
    54             // add data label to the input field.
    55             $price_adjustment[] = 'data-label="' . esc_attr( $option_label ) . '"';
    56         }
     21// Alias field_args as field for template.
     22$field = $field_args ?? array();
     23?>
    5724
    58         echo '<option value="' . esc_attr( $option_value ) . '" ' . $selected . ' ' . implode( ' ', $price_adjustment ) . '>' . $option_label . '</option>';
    59     }
    60     echo '</select>';
    61 }
    62 echo '</span>';
    63 if ( ! empty( $field_args['description'] ) ) {
    64     echo '<span id="' . esc_attr( $field_args['id'] ) . '-description" class="' . esc_attr( implode( ' ', $field_args['description_class'] ) ) . '">' . esc_html( $field_args['description'] ) . '</span>';
    65 }
     25<label for="<?php echo H::attr( $field['id'] ); ?>"
     26    class="<?php echo H::classes( $field['label_class'] ); ?>">
     27    <?php echo H::e( $field['label'] ); ?>
     28    <?php echo $required_string; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
     29</label>
     30
     31<span class="<?php echo H::classes( $field['input_wrapper_class'] ); ?>">
     32    <?php if ( ! empty( $field['options'] ) && is_array( $field['options'] ) ) : ?>
     33        <select class="select <?php echo H::classes( $field['input_class'] ); ?>"
     34            id="<?php echo H::attr( $field['id'] ); ?>"
     35            name="<?php echo H::attr( $field['name'] ); ?>"
     36            <?php echo H::join( $custom_attributes ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
     37        >
     38            <?php if ( ! empty( $field['placeholder'] ) ) : ?>
     39                <option value="" disabled selected>
     40                    <?php echo H::e( $field['placeholder'] ); ?>
     41                </option>
     42            <?php endif; ?>
     43
     44            <?php foreach ( $field['options'] as $option ) : ?>
     45                <?php
     46                $option_value = $option['value'] ?? '';
     47                $option_label = $option['label'] ?? '';
     48                $selected     = H::selected( $field['value'] ?? '', $option_value );
     49
     50                // Build data attributes for price adjustment.
     51                $data_attrs = array();
     52                if ( ! empty( $option['price_adjustment_value'] ) ) {
     53                    $data_attrs['price-adjustment']      = $option['price_adjustment_value'];
     54                    $data_attrs['price-adjustment-type'] = $option['price_adjustment_type'] ?? 'fixed';
     55                    $data_attrs['label']                 = $option_label;
     56                }
     57                ?>
     58
     59                <option value="<?php echo H::attr( $option_value ); ?>"
     60                    <?php echo $selected; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
     61                    <?php echo H::data_attrs( $data_attrs ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
     62                >
     63                    <?php echo H::e( $option_label ); ?>
     64                </option>
     65            <?php endforeach; ?>
     66        </select>
     67    <?php endif; ?>
     68</span>
     69
     70<?php if ( ! empty( $field['description'] ) ) : ?>
     71    <span id="<?php echo H::attr( $field['id'] ); ?>-description"
     72        class="<?php echo H::classes( $field['description_class'] ); ?>">
     73        <?php echo H::e( $field['description'] ); ?>
     74    </span>
     75<?php endif; ?>
  • extra-product-data-for-woocommerce/trunk/src/templates/view/fields/text.php

    r3460848 r3469202  
    11<?php
    22/**
    3  * Created on Tue Nov 26 2024
     3 * Text Field Template (Template Engine Version)
    44 *
    5  * Copyright (c) 2024 IT-Dienstleistungen Drevermann - All Rights Reserved
     5 * Variables available:
     6 * - $field: Complete field configuration
     7 * - $required_string: Required indicator HTML
     8 * - $custom_attributes: Array of custom HTML attributes
    69 *
    7  * @package Extra Product Data for WooCommerce
    8  * @author Daniel Drevermann <info@triopsi.com>
    9  * @copyright Copyright (c) 2024, IT-Dienstleistungen Drevermann
    10  *
    11  * This program is free software: you can redistribute it and/or modify
    12  * it under the terms of the GNU General Public License as published by
    13  * the Free Software Foundation, either version 2 of the License, or
    14  * (at your option) any later version.
    15  *
    16  * This program is distributed in the hope that it will be useful,
    17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    19  * GNU General Public License for more details.
    20  *
    21  * You should have received a copy of the GNU General Public License
    22  * along with this program. If not, see <https://www.gnu.org/licenses/>.
    23  *
    24  * This file is part of the development of WordPress plugins.
     10 * @package Extra_Product_Data_For_WooCommerce
     11 * @since 1.9.0
    2512 */
     13
     14use Triopsi\Exprdawc\Helper\Exprdawc_Template_Helpers as H;
     15
    2616// phpcs:ignoreFile
    2717if ( ! defined( 'ABSPATH' ) ) {
    2818    exit;
    2919}
    30 echo '<label for="' . esc_attr( $field_args['id'] ) . '" class="' . esc_attr( implode( ' ', $field_args['label_class'] ) ) . '">' . esc_html( $field_args['label'] ) . $required_string . '</label>';
    31 echo '<span class="' . esc_attr( implode( ' ', $field_args['input_wrapper_class'] ) ) . '">';
    32 echo '<input type="' . esc_attr( $field_args['type'] ) . '"
    33     class="' . esc_attr( implode( ' ', $field_args['input_class'] ) ) . '"
    34     name="' . esc_attr( $field_args['name'] ) . '"
    35     id="' . esc_attr( $field_args['id'] ) . '"
    36     placeholder="' . esc_attr( $field_args['placeholder'] ) . '"
    37     value="' . esc_attr( $field_args['value'] ) . '"
    38     ' . implode( ' ', $custom_attributes ) . ' />';
    3920
    40 if ( ! empty( $field_args['description'] ) ) {
    41     echo '<span id="' . esc_attr( $field_args['id'] ) . '-description" class="' . esc_attr( implode( ' ', $field_args['description_class'] ) ) . '">' . esc_html( $field_args['description'] ) . '</span>';
    42 }
    43 echo '</span>';
     21// Alias field_args as field for template.
     22$field = $field_args ?? array();
     23?>
     24
     25<label for="<?php echo H::attr( $field['id'] ); ?>"
     26    class="<?php echo H::classes( $field['label_class'] ); ?>">
     27    <?php echo H::e( $field['label'] ); ?>
     28    <?php echo $required_string; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
     29</label>
     30
     31<span class="<?php echo H::classes( $field['input_wrapper_class'] ); ?>">
     32    <input type="<?php echo H::attr( $field['type'] ); ?>"
     33        class="<?php echo H::classes( $field['input_class'] ); ?>"
     34        name="<?php echo H::attr( $field['name'] ); ?>"
     35        id="<?php echo H::attr( $field['id'] ); ?>"
     36        placeholder="<?php echo H::attr( $field['placeholder'] ?? '' ); ?>"
     37        value="<?php echo H::attr( $field['value'] ?? '' ); ?>"
     38        <?php echo H::join( $custom_attributes ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
     39    />
     40
     41    <?php if ( ! empty( $field['description'] ) ) : ?>
     42        <span id="<?php echo H::attr( $field['id'] ); ?>-description"
     43            class="<?php echo H::classes( $field['description_class'] ); ?>">
     44            <?php echo H::e( $field['description'] ); ?>
     45        </span>
     46    <?php endif; ?>
     47</span>
  • extra-product-data-for-woocommerce/trunk/src/templates/view/fields/textarea.php

    r3460848 r3469202  
    11<?php
    22/**
    3  * Created on Tue Nov 26 2024
     3 * Textarea Field Template (Template Engine Version)
    44 *
    5  * Copyright (c) 2024 IT-Dienstleistungen Drevermann - All Rights Reserved
     5 * Variables available:
     6 * - $field: Complete field configuration
     7 * - $required_string: Required indicator HTML
     8 * - $custom_attributes: Array of custom HTML attributes
    69 *
    7  * @package Extra Product Data for WooCommerce
    8  * @author Daniel Drevermann <info@triopsi.com>
    9  * @copyright Copyright (c) 2024, IT-Dienstleistungen Drevermann
    10  *
    11  * This program is free software: you can redistribute it and/or modify
    12  * it under the terms of the GNU General Public License as published by
    13  * the Free Software Foundation, either version 2 of the License, or
    14  * (at your option) any later version.
    15  *
    16  * This program is distributed in the hope that it will be useful,
    17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    19  * GNU General Public License for more details.
    20  *
    21  * You should have received a copy of the GNU General Public License
    22  * along with this program. If not, see <https://www.gnu.org/licenses/>.
    23  *
    24  * This file is part of the development of WordPress plugins.
     10 * @package Extra_Product_Data_For_WooCommerce
     11 * @since 1.9.0
    2512 */
     13
     14use Triopsi\Exprdawc\Helper\Exprdawc_Template_Helpers as H;
     15
    2616// phpcs:ignoreFile
    2717if ( ! defined( 'ABSPATH' ) ) {
     
    2919}
    3020
    31 echo '<label for="' . esc_attr( $field_args['id'] ) . '" class="' . esc_attr( implode( ' ', $field_args['label_class'] ) ) . '">' . esc_html( $field_args['label'] ) . $required_string . '</label>';
    32 echo '<span class="' . esc_attr( implode( ' ', $field_args['input_wrapper_class'] ) ) . '">';
    33 echo '<textarea
    34     name="' . esc_attr( $field_args['name'] ) . '"
    35     class="' . esc_attr( implode( ' ', $field_args['input_class'] ) ) . '"
    36     id="' . esc_attr( $field_args['id'] ) . '"
    37     placeholder="' . esc_attr( $field_args['placeholder'] ) . '" ' .
    38     implode( ' ', $custom_attributes ) . '>' .
    39     esc_textarea( $field_args['value'] ) .
    40     '</textarea>';
    41 if ( ! empty( $field_args['description'] ) ) {
    42     echo '<span id="' . esc_attr( $field_args['id'] ) . '-description" class="' . esc_attr( implode( ' ', $field_args['description_class'] ) ) . '">' . esc_html( $field_args['description'] ) . '</span>';
    43 }
    44 echo '</span>';
     21// Alias field_args as field for template.
     22$field = $field_args ?? array();
     23?>
     24
     25<label for="<?php echo H::attr( $field['id'] ); ?>"
     26    class="<?php echo H::classes( $field['label_class'] ); ?>">
     27    <?php echo H::e( $field['label'] ); ?>
     28    <?php echo $required_string; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
     29</label>
     30
     31<span class="<?php echo H::classes( $field['input_wrapper_class'] ); ?>">
     32    <textarea name="<?php echo H::attr( $field['name'] ); ?>"
     33        class="<?php echo H::classes( $field['input_class'] ); ?>"
     34        id="<?php echo H::attr( $field['id'] ); ?>"
     35        placeholder="<?php echo H::attr( $field['placeholder'] ?? '' ); ?>"
     36        <?php echo H::join( $custom_attributes ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
     37    ><?php echo H::textarea( $field['value'] ?? '' ); ?></textarea>
     38
     39    <?php if ( ! empty( $field['description'] ) ) : ?>
     40        <span id="<?php echo H::attr( $field['id'] ); ?>-description"
     41            class="<?php echo H::classes( $field['description_class'] ); ?>">
     42            <?php echo H::e( $field['description'] ); ?>
     43        </span>
     44    <?php endif; ?>
     45</span>
  • extra-product-data-for-woocommerce/trunk/src/templates/view/html-tab-extra-attributes.php

    r3460848 r3469202  
    2929}
    3030?>
    31 <input type="hidden" id="exprdawc_export_string" name="exprdawc_export_string" value="<?php echo $custom_fields ? wc_esc_json( json_encode( $custom_fields ) ) : ''; // phpcs:ignore ?>" />
     31<input type="hidden" id="exprdawc_export_string" name="exprdawc_export_string" value="<?php echo $args['custom_fields'] ? wc_esc_json( json_encode( $args['custom_fields'] ) ) : ''; // phpcs:ignore ?>" />
     32
     33<?php
     34// Include the import/export modal template.
     35require EXPRDAWC_TEMPLATES . 'modal-import-export.php';
     36?>
     37
    3238<div id="extra-product-data" class="panel woocommerce_options_panel exprdawc_panel_wrapper">
    3339    <div class="toolbar toolbar-top">
     
    4551                <tbody id="exprdawc_field_body">
    4652                <?php
    47                 if ( ! empty( $custom_fields ) ) {
     53                if ( ! empty( $args['custom_fields'] ) ) {
    4854                    $all_fields = array();
    4955                    // Loop through all fields and include the template.
    50                     foreach ( $custom_fields as $index => $field ) {
     56                    foreach ( $args['custom_fields'] as $index => $field ) {
    5157                        $all_fields[ $field['label'] ] = $field['label'];
    5258                    }
    53                     foreach ( $custom_fields as $index => $field ) {
     59                    foreach ( $args['custom_fields'] as $index => $field ) {
    5460                        $field['price_adjustment_type'] = isset( $field['price_adjustment_type'] ) ? $field['price_adjustment_type'] : '';
    5561                        echo '<tr class="exprdawc_fields_wrapper">';
Note: See TracChangeset for help on using the changeset viewer.