Skip to content

3.7.0

Choose a tag to compare

@PaulArgoud PaulArgoud released this 19 Feb 02:19
· 32 commits to main since this release

Added

  • Forms module: Elementor Pro, Divi & Bricks support — Extends the existing Forms module with 3 new form plugin integrations. Hooks: elementor_pro/forms/new_record, et_pb_contact_form_submit, bricks/form/custom_action. Field extraction via Form_Field_Extractor normalizer. 3 new setting toggles
  • Food Ordering module: RestroPress support — Extends the existing Food Ordering module with RestroPress integration. Hooks: restropress_complete_purchase. Extraction via Food_Order_Extractor::extract_from_restropress(). New sync_restropress setting toggle
  • Fluent Support module — New helpdesk module extending Helpdesk_Module_Base. Syncs tickets → helpdesk.ticket (Enterprise) with project.task fallback (Community). Hooks: fluent_support/ticket_created, fluent_support/ticket_updated, fluent_support/response_added. Configurable Helpdesk Team ID and Project ID
  • Sensei LMS module — New LMS module extending LMS_Module_Base. Syncs courses → product.product (bidirectional), orders → account.move (push, auto-post), enrollments → sale.order (push, synthetic ID encoding). Hooks: save_post_course, sensei_course_status_updated, woocommerce_order_status_changed (filtered for Sensei orders). Version bounds: Sensei 4.0–4.24
  • Ultimate Member module — New user profile module. Syncs profiles → res.partner (bidirectional), roles → res.partner.category (push-only). Custom field enrichment (phone, company, country, city). Hooks: um_after_user_updated, um_registration_complete, um_delete_user, um_member_role_upgrade, um_member_role_downgrade. Version bounds: UM 2.6–2.9
  • WC Rental module — New WooCommerce extension module. Syncs rental orders → sale.order with Odoo Rental fields (is_rental, pickup_date, return_date). Generic approach: configurable meta keys for rental product detection and date extraction. Requires WooCommerce module. Hook: woocommerce_order_status_changed (priority 20, after WC module)
  • Field Service module — New bidirectional CPT module. Syncs field service tasks between wp4odoo_fs_task CPT and Odoo field_service.task (Enterprise). Admin-visible CPT under WP4Odoo menu. Status mapping (draft↔New, publish↔In Progress, private↔Done). Meta fields: planned date, deadline, priority. Dedup by task name
  • Odoo_Model enum: FieldServiceTask — New field_service.task case for Field Service module
  • WC_Order_Item::get_meta() — Added get_meta() method to WC_Order_Item stubs (PHPStan + PHPUnit) for order item meta access
  • Schema_Cache::flush_all() — New method that deletes both in-memory and persistent (transient) caches in one query. Fires wp4odoo_schema_cache_flushed action after cleanup for third-party extensibility
  • WP-CLI cache flush commandwp wp4odoo cache flush clears the Odoo schema cache (memory + transients) on demand
  • wp4odoo_retry_delay filter — Retry delay in Sync_Job_Tracking::handle_failure() is now filterable. Clamped to [0, MAX_RETRY_DELAY] for safety

Fixed (Architecture)

  • Exponential backoff capSync_Job_Tracking::calculate_retry_delay() now caps retry delay at 3600s (MAX_RETRY_DELAY). Without a cap, high attempt counts produced delays exceeding practical bounds
  • Stale recovery loop preventionSync_Queue_Repository::recover_stale_processing() now increments attempts when recovering stale jobs. Prevents infinite recovery loops where a job that consistently crashes is recovered and reprocessed indefinitely without progressing toward max_attempts (reverses 3.6.0 "no-increment" behavior — a job that repeatedly stalls IS progressing toward failure)
  • SQL injection hardeningSync_Queue_Repository::enqueue() and cleanup() now use $wpdb->prepare() for status IN (...) clauses (was safe hardcoded values, but inconsistent with the fully-prepared pattern used elsewhere)
  • Atomic stale recovery guardSync_Engine::process_queue() now uses wp_cache_add() for the stale recovery mutex (was non-atomic get_transient()/set_transient() — two concurrent crons could both pass the check)
  • Multisite settings cache scopingSettings_Repository internal cache is now keyed by blog_id. On multisite, switch_to_blog() previously returned cached settings from the originating site

Fixed (Multisite)

  • Credential cache flush on switch_blogwp4odoo.php now hooks switch_blog to call Odoo_Auth::flush_credentials_cache(), preventing stale credentials from site A leaking into site B when using switch_to_blog()

Fixed (Modules)

  • Sales_Module handler init — Moved Portal_Manager and Partner_Service initialization from boot() to __construct(), consistent with all other modules. Prevents potential uninitialized property access if portal_manager is referenced before boot() is called

Changed

  • SSL verification warningOdoo_JsonRPC and Odoo_XmlRPC now log a warning when WP4ODOO_DISABLE_SSL_VERIFY is active, making the insecure configuration visible in logs
  • PHP 8.1+ first-class callable syntax — Replaced 17 string-based callables ('intval', 'strval') with first-class callable syntax (intval( ... ), strval( ... )) across 9 files. Better IDE support, type-safe, catches typos at parse time
  • PHP 8.0+ str_contains() — Replaced 2 strpos() !== false patterns with str_contains() in GamiPress_Handler

CI

  • Composer audit — Added composer audit --no-dev step to GitHub Actions CI pipeline to detect known vulnerabilities in dependencies

Tests

  • Updated SyncQueueRepositoryTest — 2 tests adapted: stale recovery now asserts attempts increment, cleanup test matches prepared IN (%s, %s) pattern
  • Removed duplicate documents-classes.php stub require in tests/bootstrap.php