Skip to content

Releases: PaulArgoud/woocommerce-subscriptions-tax-retrofit

1.4.4

Choose a tag to compare

@PaulArgoud PaulArgoud released this 08 Feb 01:36

Consistency

  • Unescaped $interrupted_offset in resume form: get_option('wc_tax_retrofit_current_offset') output was interpolated directly in an HTML hidden input value attribute without intval(). Internal integer with no user input path, but inconsistent with the systematic escaping applied in v1.4.2. Fixed with intval()
  • Unescaped $checked in status checkboxes: hardcoded 'checked' / '' string output without esc_attr() in the subscription status fieldset, while the adjacent $status_key was already escaped. Fixed with esc_attr()

1.4.3

Choose a tag to compare

@PaulArgoud PaulArgoud released this 08 Feb 01:12

Robustness

  • catch (Exception)catch (\Throwable) in get_tax_rate_id(): the try/catch around WC_Tax::find_rates() only caught Exception. A TypeError or Error thrown by WooCommerce would propagate uncaught. Fixed with \Throwable (consistent with the two catches in process() fixed in 1.4.1)
  • Missing batch_size and offset keys in tax-rate-not-found return: when get_tax_rate_id() returns null, process() returned an early error array missing batch_size and offset keys, unlike all other return paths. Code consuming $stats['batch_size'] or $stats['offset'] (e.g. display_results()) would trigger an undefined index notice

Consistency

  • JSON_UNESCAPED_UNICODE in CLI simulate: wp tax-retrofit simulate --json output escaped Unicode characters (e.g. French accents as \u00e9). Added JSON_UNESCAPED_UNICODE flag for readable output
  • Plugin header Description translated to English: the WordPress plugin header Description field was still in French. Rewritten in English for consistency with the rest of the project documentation

1.4.2

Choose a tag to compare

@PaulArgoud PaulArgoud released this 08 Feb 01:00

Consistency

  • Systematic escaping in display_results(): $mode_color, $percent, $processed, $stats['total'], $stats['batch_size'], $stats['offset'], $stats['updated'], $stats['skipped'], $stats['errors'], $remaining, $eta_minutes, $eta_sec_remain and $next were interpolated directly in HTML output without intval() or esc_attr(). All internal values with no user input path, but inconsistent with the rest of the plugin which escapes systematically. Fixed with intval() for integers and esc_attr() for attributes
  • Unescaped $style in tax rate debug table: hardcoded CSS string output without esc_attr() in admin_page(). Fixed
  • Unescaped $diff in tax rate debug table: float difference output without esc_html() while all other values in the same table row were escaped. Fixed with esc_html(number_format(...))
  • Loose comparison == for rate selection: $current_rate_id == $rate_id used loose comparison where null == 0 evaluates to true. Replaced with (int) === (int) strict comparison
  • Redundant tolerance validation: validate_tolerance() and a manual bounds check were both applied on the same input. Simplified to a single validate_float() call
  • Translation file version headers: .pot, fr_FR.po and en_US.po still referenced version 1.4.0 instead of current version

1.4.1

Choose a tag to compare

@PaulArgoud PaulArgoud released this 08 Feb 00:42

Robustness

  • catch (Exception)catch (\Throwable): both try/catch blocks in process() (per-subscription transaction + outer loop) only caught Exception. In PHP 7+, TypeError and Error are not subclasses of Exception — a WooCommerce TypeError crash would leave the transaction open without ROLLBACK. Fixed with \Throwable
  • Float comparison == 0 in detect_no_tax_date(): array_sum($taxes['total']) == 0 could produce a false positive for values very close to 0 (e.g. 0.0001). Replaced with abs(array_sum($taxes['total'])) < 0.001

Performance

  • Transient cache for detect_no_tax_date(): automatic date detection (N+1 queries across 50 subscriptions) ran on every admin page load when no date was configured. Result now cached in a 5-minute transient (wc_tax_retrofit_detect_date_desc / _asc)
  • Static cache for get_tax_rate_id(): tax rate lookup (up to 4 DB queries) was not cached, unlike other getters. Added static cache with dual variables ($cached + $cached_resolved) to support the null case
  • Static cache for count_subscriptions(): total count (wcs_get_subscriptions with limit => -1) was not cached. Added static cache and deduplicated the inline code in process() that replicated the same logic

Consistency

  • $wpdb->prepare() on debug query step 4: the only SQL query in the plugin not using prepare() (available rates listing in get_tax_rate_id()). Fixed with LIMIT %d
  • Sanitize $_POST['statuses']: status checkboxes input was not passed through sanitize_text_field() before validate_statuses(). Near-zero risk (whitelist downstream) but inconsistent with other inputs
  • Cleanup detect_date_* transients: both new transients are now deleted in deactivate() and uninstall.php

Documentation

  • README.md: 3 occurrences of the old name woocommerce-subscription-tax-retrofit corrected to wcs-tax-retrofit (renamed since v1.3.5)

v1.4.0

Choose a tag to compare

@PaulArgoud PaulArgoud released this 08 Feb 00:33

Full internationalization

  • ~70 untranslatable UI strings: most admin interface texts (admin_page(), display_results(), ajax_count(), CSV headers) were raw French without __() calls. All strings now wrapped in __(), esc_html__() or esc_js() as appropriate. Translation files grew from ~62 to ~130 entries
  • Regenerated .po/.pot files: all 3 translation files rewritten with new entries and updated versions

Fixes

  • Missing batch_size and csv_data: the $stats array returned on dependency errors in process() lacked batch_size, offset and csv_data keys, causing undefined index in calling code
  • get_all_tax_rates() without $wpdb->prepare(): SQL query used direct interpolation instead of $wpdb->prepare(), inconsistent with the rest of the plugin. Fixed with parameterized LIMIT %d