From db9ba2bacd2b78363433ce5757b48ea3a5446ed2 Mon Sep 17 00:00:00 2001 From: magdev Date: Mon, 22 Dec 2025 23:29:35 +0100 Subject: [PATCH] Release version 1.1.18 - Fix root cause of duplicate settings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Identified and fixed the actual root cause of duplicate settings page: automatic instantiation in settings file being executed multiple times. Root Cause Analysis: - Settings file ended with: return new WC_TPP_Settings(); - File is in Composer's classmap for autoloading - When autoloader loads class, it executes the entire file including instantiation - Each include/autoload created a NEW instance despite admin singleton pattern - Admin singleton prevented multiple admin instances but not multiple settings instances The Fix: - Removed automatic instantiation (return new) from settings file - Settings file now only contains class definition - Admin class explicitly creates instance: new WC_TPP_Settings() - Changed from include to require_once to prevent multiple file loads - Settings instance now created exactly once, when filter needs it Fixes: - Settings page rendering twice in WooCommerce backend - Multiple WC_TPP_Settings instances being created - Composer autoload triggering unintended instantiation Changes: - Removed line 145 from class-wc-tpp-settings.php (return new WC_TPP_Settings()) - Modified add_settings_page() to use require_once + explicit new - Settings file now side-effect free, safe for autoloading Technical Details: - Composer classmap autoloader includes files when class is referenced - Previous code had side effect (instantiation) on every include - New code separates class definition from instantiation - Instance creation now controlled explicitly by admin class - require_once ensures file loaded once even if accessed multiple times Updated Files: - includes/class-wc-tpp-settings.php (removed return new line) - includes/class-wc-tpp-admin.php (explicit instantiation) - wc-tier-and-package-prices.php (version 1.1.18) - composer.json (version 1.1.18) - CHANGELOG.md (v1.1.18 section) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- CHANGELOG.md | 22 ++++++++++++++++++++++ composer.json | 2 +- includes/class-wc-tpp-admin.php | 3 ++- includes/class-wc-tpp-settings.php | 2 -- wc-tier-and-package-prices.php | 4 ++-- 5 files changed, 27 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ef6a28c..ab8423e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,28 @@ All notable changes to WooCommerce Tier and Package Prices will be documented in The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.1.18] - 2025-12-22 + +### Fixed + +- **ROOT CAUSE IDENTIFIED**: Settings page rendering twice due to automatic instantiation in settings file +- Settings file being included multiple times via Composer autoloader creating duplicate instances + +### Changed + +- Removed `return new WC_TPP_Settings();` from bottom of settings file +- Changed admin class to explicitly instantiate settings with `new WC_TPP_Settings()` +- Changed from `include` to `require_once` for settings file to prevent multiple loads + +### Technical Details + +- Settings file (class-wc-tpp-settings.php) was creating instance automatically on include +- File is in Composer's classmap, so when autoloaded it executed instantiation again +- Each include/autoload created new instance even with singleton pattern in admin class +- Solution: Remove automatic instantiation, use `require_once` + explicit `new` in admin class +- Now settings instance only created once, explicitly, when needed by filter +- Composer autoload can load class definition without side effects + ## [1.1.17] - 2025-12-22 ### Fixed diff --git a/composer.json b/composer.json index cefa5e6..d8c9991 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "magdev/wc-tier-package-prices", "description": "WooCommerce plugin for tier pricing and package prices with Twig templates", - "version": "1.1.17", + "version": "1.1.18", "type": "wordpress-plugin", "license": "GPL-2.0-or-later", "authors": [ diff --git a/includes/class-wc-tpp-admin.php b/includes/class-wc-tpp-admin.php index 96b9241..cded785 100644 --- a/includes/class-wc-tpp-admin.php +++ b/includes/class-wc-tpp-admin.php @@ -30,7 +30,8 @@ if (!class_exists('WC_TPP_Admin')) { */ public function add_settings_page($settings) { if (null === self::$settings_instance) { - self::$settings_instance = include WC_TPP_PLUGIN_DIR . 'includes/class-wc-tpp-settings.php'; + require_once WC_TPP_PLUGIN_DIR . 'includes/class-wc-tpp-settings.php'; + self::$settings_instance = new WC_TPP_Settings(); } // Check if our settings page is already in the array to prevent duplicates diff --git a/includes/class-wc-tpp-settings.php b/includes/class-wc-tpp-settings.php index a370e83..5cfdd12 100644 --- a/includes/class-wc-tpp-settings.php +++ b/includes/class-wc-tpp-settings.php @@ -141,5 +141,3 @@ if (!class_exists('WC_TPP_Settings')) { } } } - -return new WC_TPP_Settings(); diff --git a/wc-tier-and-package-prices.php b/wc-tier-and-package-prices.php index 7c808a0..ae7b7ff 100644 --- a/wc-tier-and-package-prices.php +++ b/wc-tier-and-package-prices.php @@ -4,7 +4,7 @@ * Plugin Name: WooCommerce Tier and Package Prices * Plugin URI: https://src.bundespruefstelle.ch/magdev/wc-tier-package-prices * Description: Add tier pricing and package prices to WooCommerce products with configurable quantities at fixed prices - * Version: 1.1.17 + * Version: 1.1.18 * Author: Marco Graetsch * Author URI: https://src.bundespruefstelle.ch/magdev * Text Domain: wc-tier-package-prices @@ -23,7 +23,7 @@ if (!defined('ABSPATH')) { // Define plugin constants if (!defined('WC_TPP_VERSION')) { - define('WC_TPP_VERSION', '1.1.17'); + define('WC_TPP_VERSION', '1.1.18'); } if (!defined('WC_TPP_PLUGIN_DIR')) { define('WC_TPP_PLUGIN_DIR', plugin_dir_path(__FILE__));