8 Commits

Author SHA1 Message Date
0ade909bd9 fix: correct nested error message extraction + listSubscriberAdd params
Error message extraction:
- phpList v3 nests the actual message inside data.message:
    {"status":"error","data":{"code":0,"message":"invalid call"}}
  Previous code read data as a raw value and got "Array" in the logs.
  Now checks data.message first, falls back to top-level fields.

listSubscriberAdd:
- Send both naming conventions (listid/subscriberid AND list_id/subscriber_id)
  so the call works regardless of which phpList REST API build is installed.
- Add debug log line showing exact param values sent, making future
  diagnosis straightforward without needing server-side inspection.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 08:30:39 +01:00
72d237a066 fix: extract subscriber ID from nested data field in phpList response
phpList REST API v3 returns subscriber data wrapped in a "data" key:
  {"status":"success","type":"Subscriber","data":{"id":"2400",...}}

Both subscriber_get_by_email and subscriber_add responses are now read as
response['data']['id'] with a fallback to response['id'] for compatibility.
Previously the code checked only response['id'] (top level), found nothing,
and reported failure even though the subscriber was created successfully.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 08:22:40 +01:00
1c382f2cf4 fix: send API params in POST body, remove double URL-encoding
Root causes identified from logs:
1. All params (login, password, cmd, email, etc.) were appended to the URL
   query string; phpList REST API v3 expects them in the POST body.
   wp_remote_post now sends body=>$params instead of an empty body.
2. subscriber_get_by_email and subscriber_add called rawurlencode() on the
   email before passing it to call(), which then ran http_build_query() on
   it again — double-encoding '@' to '%2540'. Both rawurlencode() calls
   removed; wp_remote_post handles POST body encoding correctly.

Additional improvements:
- endpoint_url() returns just the bare ?page=call&pi=restapi URL
- On API error, log full_response (entire JSON) not just the message field,
  so phpList's exact reply is always visible in WC Status Logs
- Non-JSON response now gives an explicit error message pointing to the
  endpoint URL / credentials rather than a generic JSON parse failure

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 08:18:43 +01:00
7f1f351ff1 fix: meta box visibility + add WooCommerce Order Actions dropdown entries
Meta box:
- Replace generic add_meta_boxes hook with screen-specific
  add_meta_boxes_shop_order and add_meta_boxes_woocommerce_page_wc-orders
  so the box reliably appears on both classic and HPOS order edit pages

Order Actions dropdown:
- Hook woocommerce_order_actions filter to inject "phpList: Add to X list"
  entries for every configured list (only lists with a saved ID appear)
- Register individual woocommerce_order_action_woolist_sync_{list_id}
  handlers via closures at init time so WooCommerce can process them
- Shared do_sync() used by both the dropdown action and the meta box AJAX;
  appends an order note (visible in order timeline) on success or failure

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 08:06:05 +01:00
9b1d653789 feat: WC-native logging + Add to phpList button on order page
Logging:
- Replace custom file logger with wc_get_logger() (source: woolist-phplist)
- Logs now appear in WooCommerce → Status → Logs, no filesystem access needed
- Remove log viewer / Clear Log from settings page (WC UI handles this)
- Keep "Enable debug logging" checkbox to control DEBUG-level verbosity

Order page meta box:
- New "phpList Sync" side meta box on every order edit page
- Works with both classic (shop_order) and HPOS (woocommerce_page_wc-orders)
- Shows billing email + dropdown of all configured lists
- "Add to phpList" button triggers AJAX subscribe, shows inline result
- Result and full API trace logged to WC logs under woolist-phplist source
- woolist-admin.js handles button state and response display

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 08:00:05 +01:00
f4c9e39493 feat: add structured file-based logging with admin log viewer
- New WooList_Logger class writes to wp-content/uploads/woolist-logs/woolist.log
  - INFO level: subscription events, test connection results (always recorded)
  - ERROR level: API failures, config problems (always recorded + php error_log fallback)
  - DEBUG level: full request URLs (password redacted), raw responses, step-by-step
    flow (only when "Enable debug logging" is checked in settings)
  - Auto-rotates at 1 MB; log directory protected by .htaccess
- API class: logs every request URL (redacted) and raw response body at DEBUG,
  errors at ERROR; subscribe_email_to_list logs each step (lookup/create/add)
- Hooks class: logs hook fire, skip reasons, and sync intent at DEBUG/INFO/ERROR
- Shortcode class: logs AJAX submissions, coupon generation, and failures
- Admin: new Logging section with "Enable debug logging" checkbox;
  log viewer textarea (last 300 lines, dark theme) + Clear Log button
  both visible at bottom of WooCommerce → Settings → phpList tab

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-19 16:25:33 +01:00
0429a282bc feat: add Spanish (es_ES) and Romanian (ro_RO) translations
- Generate woolist-phplist.pot from all 48 translatable strings
- Add full es_ES.po / ro_RO.po with translations for all strings
- Compile binary .mo files for both locales
- Add load_plugin_textdomain() call so WordPress loads the translations

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-19 13:09:12 +01:00
6e23e40bf3 feat: initial implementation of WooList phpList Integration plugin v1.0.0
- phpList REST API wrapper with subscriber get-or-create + list assignment
- WooCommerce Settings tab (5 sections: connection, orders, signup, newsletter)
- Test Connection button via admin-post action
- Hooks for order completed/cancelled and user_register events
- [woolist_newsletter] shortcode with jQuery AJAX, fixed & auto-generated coupons
- Responsive front-end form styles and JS with loading/success/error states

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-19 11:51:12 +01:00