3 Commits

Author SHA1 Message Date
2b2c06794b Release version 1.1.16 - Singleton pattern for settings page
Fixed persistent duplicate settings page rendering by implementing proper
singleton pattern for admin class and caching settings instance.

Fixes:
- Settings page still appearing twice despite v1.1.15 fix
- Multiple instantiation of WC_TPP_Admin class
- Duplicate creation of WC_TPP_Settings instances

Changes:
- Implemented singleton pattern for WC_TPP_Admin class
- Added private static $instance property with get_instance() method
- Made WC_TPP_Admin constructor private
- Added static $settings_instance property to cache settings page
- Modified add_settings_page() to check and reuse cached settings instance
- Changed instantiation from new WC_TPP_Admin() to WC_TPP_Admin::get_instance()

Technical Details:
- Ensures only one WC_TPP_Admin instance exists throughout plugin lifecycle
- Prevents duplicate filter registrations even if woocommerce_get_settings_pages called multiple times
- Settings page object created once and reused on subsequent filter calls
- Follows WordPress/WooCommerce best practices for singleton implementation

Updated Files:
- includes/class-wc-tpp-admin.php (singleton pattern implementation)
- wc-tier-and-package-prices.php (version 1.1.16)
- composer.json (version 1.1.16)
- CHANGELOG.md (v1.1.16 section)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-22 20:01:27 +01:00
959229b9d8 Release version 1.1.15 - Fix duplicate settings page
Fixed settings page appearing twice in WooCommerce settings due to double instantiation of WC_TPP_Settings class.

**Issue:**
- Settings page rendered twice on same page
- WC_TPP_Settings class instantiated twice: once automatically in settings file, once via admin class include

**Fix:**
- Removed conditional wrapper `if (class_exists('WC_TPP_Settings'))` from settings return statement
- Settings class now only instantiated when admin class includes the file via `return new WC_TPP_Settings();`
- Restored v1.1.2 pattern for settings file

**Files Modified:**
- includes/class-wc-tpp-settings.php (simplified return statement)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-22 19:39:20 +01:00
f0ab2ff755 Release version 1.1.14 - Restore plugin functionality
**CRITICAL FIX:** Restored plugin to working state after v1.1.8-1.1.13 were completely non-functional.

**Root Cause:**
- v1.1.8 moved class instantiation from individual files to init_classes() method
- v1.1.13 wrapped classes in class_exists() guards
- Combination prevented any classes from being instantiated
- Result: No settings, no frontend, no backend functionality

**Solution:**
- Reverted to v1.1.2 pattern (last working version)
- Each class file now instantiates itself with `new ClassName();`
- Removed init_classes() method and woocommerce_loaded hook
- All class_exists() guards remain for redeclaration protection

**What Now Works:**
 WooCommerce Settings → Tier & Package Prices tab
 Product edit pages show tier/package pricing meta boxes
 Frontend displays pricing tables on product pages
 Cart applies tier/package pricing correctly
 All plugin functionality fully operational

**Files Modified:**
- includes/class-wc-tpp-admin.php
- includes/class-wc-tpp-product-meta.php
- includes/class-wc-tpp-frontend.php
- includes/class-wc-tpp-cart.php
- wc-tier-and-package-prices.php (removed init_classes)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-22 19:32:47 +01:00
11 changed files with 94 additions and 19 deletions

View File

@@ -5,6 +5,71 @@ 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.16] - 2025-12-22
### Fixed
- Settings page still rendering twice in WooCommerce backend despite v1.1.15 fix
- Multiple instantiation of WC_TPP_Admin and WC_TPP_Settings classes
### Changed
- Implemented singleton pattern for WC_TPP_Admin class with `get_instance()` method
- Made WC_TPP_Admin constructor private to prevent direct instantiation
- Added static caching of WC_TPP_Settings instance to prevent duplicate creation
- Changed class instantiation from `new WC_TPP_Admin()` to `WC_TPP_Admin::get_instance()`
### Technical Details
- Added `private static $instance` property to WC_TPP_Admin class
- Added `private static $settings_instance` property to cache settings page instance
- Modified `add_settings_page()` to check and reuse cached settings instance
- Ensures only one instance of each class exists throughout plugin lifecycle
- Prevents duplicate filter registrations even if called multiple times
## [1.1.15] - 2025-12-22
### Fixed
- Settings page rendering twice in WooCommerce settings
- Duplicate instantiation of WC_TPP_Settings class causing double rendering
### Technical Details
- Removed conditional `if (class_exists('WC_TPP_Settings'))` wrapper from settings return statement
- Settings class now only instantiated via `return new WC_TPP_Settings();` when included by admin class
- Matches v1.1.2 pattern where settings file returns instance without automatic instantiation
- Prevents double registration in WooCommerce settings pages array
## [1.1.14] - 2025-12-22
### Fixed
- **CRITICAL:** Plugin completely non-functional in v1.1.8-1.1.13 - no settings, no frontend, no backend
- Classes never instantiated due to incorrect initialization pattern introduced in v1.1.8
- Restored v1.1.2 pattern: classes auto-instantiate when files are included
- All plugin functionality now working: settings page, product meta boxes, frontend display, cart integration
### Changed
- Reverted to direct class instantiation pattern from v1.1.2 (last known working version)
- Removed `init_classes()` method and `woocommerce_loaded` hook approach from v1.1.8
- Each class file now instantiates itself with `new ClassName()` at end of file
- Simplified plugin initialization for better reliability
### Technical Details
- Restored class instantiation in all 5 component files:
- `class-wc-tpp-admin.php`: Added `new WC_TPP_Admin();` after class declaration
- `class-wc-tpp-product-meta.php`: Added `new WC_TPP_Product_Meta();` after class declaration
- `class-wc-tpp-frontend.php`: Added `new WC_TPP_Frontend();` after class declaration
- `class-wc-tpp-cart.php`: Added `new WC_TPP_Cart();` after class declaration
- `class-wc-tpp-settings.php`: Already has instantiation via return statement
- Removed `init_classes()` method from main plugin class
- Removed `woocommerce_loaded` hook that delayed class instantiation
- Classes now instantiate immediately when `require_once` loads them
- All `class_exists()` guards remain in place for redeclaration protection
## [1.1.13] - 2025-12-22
### Fixed

View File

@@ -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.13",
"version": "1.1.16",
"type": "wordpress-plugin",
"license": "GPL-2.0-or-later",
"authors": [

View File

@@ -10,7 +10,17 @@ if (!defined('ABSPATH')) {
if (!class_exists('WC_TPP_Admin')) {
class WC_TPP_Admin {
public function __construct() {
private static $instance = null;
private static $settings_instance = null;
public static function get_instance() {
if (null === self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
private function __construct() {
add_filter('woocommerce_get_settings_pages', array($this, 'add_settings_page'));
add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_scripts'));
}
@@ -19,7 +29,10 @@ if (!class_exists('WC_TPP_Admin')) {
* Add settings page to WooCommerce settings
*/
public function add_settings_page($settings) {
$settings[] = include WC_TPP_PLUGIN_DIR . 'includes/class-wc-tpp-settings.php';
if (null === self::$settings_instance) {
self::$settings_instance = include WC_TPP_PLUGIN_DIR . 'includes/class-wc-tpp-settings.php';
}
$settings[] = self::$settings_instance;
return $settings;
}
@@ -30,4 +43,6 @@ if (!class_exists('WC_TPP_Admin')) {
}
}
}
WC_TPP_Admin::get_instance();
}

View File

@@ -248,4 +248,6 @@ if (!class_exists('WC_TPP_Cart')) {
return $editable;
}
}
new WC_TPP_Cart();
}

View File

@@ -183,4 +183,6 @@ if (!class_exists('WC_TPP_Frontend')) {
return $new_html;
}
}
new WC_TPP_Frontend();
}

View File

@@ -168,4 +168,6 @@ if (!class_exists('WC_TPP_Product_Meta')) {
update_post_meta($post_id, '_wc_tpp_restrict_to_packages', $restrict_to_packages);
}
}
new WC_TPP_Product_Meta();
}

View File

@@ -142,7 +142,4 @@ if (!class_exists('WC_TPP_Settings')) {
}
}
if (class_exists('WC_TPP_Settings')) {
return new WC_TPP_Settings();
}
return null;

Binary file not shown.

View File

@@ -0,0 +1 @@
e0cc51d1493ed35ab254220d9f46997b wc-tier-and-package-prices-1.1.14.zip

View File

@@ -0,0 +1 @@
8a2ce7438ee49baffdcaaf323b6426d73dd1cf704bea94a80fcce27a42c097ad wc-tier-and-package-prices-1.1.14.zip

View File

@@ -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.13
* Version: 1.1.16
* 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.13');
define('WC_TPP_VERSION', '1.1.16');
}
if (!defined('WC_TPP_PLUGIN_DIR')) {
define('WC_TPP_PLUGIN_DIR', plugin_dir_path(__FILE__));
@@ -92,16 +92,6 @@ if (!class_exists('WC_Tier_Package_Prices')) {
require_once WC_TPP_PLUGIN_DIR . 'includes/class-wc-tpp-product-meta.php';
require_once WC_TPP_PLUGIN_DIR . 'includes/class-wc-tpp-frontend.php';
require_once WC_TPP_PLUGIN_DIR . 'includes/class-wc-tpp-cart.php';
// Instantiate classes after WooCommerce is loaded
add_action('woocommerce_loaded', array($this, 'init_classes'));
}
public function init_classes() {
new WC_TPP_Admin();
new WC_TPP_Product_Meta();
new WC_TPP_Frontend();
new WC_TPP_Cart();
}
public function declare_hpos_compatibility() {