Skip to main content

Rentiva v4.38.1 — Audit-driven patch

· 4 min read
MaxHandMade
Maintainer

A small but important patch on top of v4.38.0. After the Vendor Directory release we ran a /wp-conductor post-merge audit on the v4.37.0 → v4.38.0 chain — two real findings and a dormant production defect surfaced from the new test coverage. v4.38.1 closes them all so the six-release deploy bundle is clean.

Written before 6.0.0

This post is the record of a release that shipped before 6.0.0, which renamed the plugin's post types, taxonomies, options, meta keys and hooks. The identifiers below are the names those versions actually used, and they are kept that way on purpose. For the current names — and a conversion table — see the 6.0.7 release post.

What changed

🔴 YÜKSEK — Admin slug edit collision

When you edited a vendor's profile slug from the WordPress admin, the save path was writing the slug directly via update_user_meta() instead of going through VendorSlugManager::change_slug(). A leftover // later TODO from v4.37.0 Phase 1.3.

The practical impact: two admins (or admin + a vendor self-editing) submitting the same raw slug to different vendors would both succeed. VendorProfileProvider::lookup_by_slug() returns the first match, so the second vendor's public profile URL silently rendered the wrong vendor — for paying Pro customers, on a marketplace, indefinitely.

The save path now routes through change_slug(), which already handles sanitize + collision suffix (-2, -3...) + history sanitize atomically.

🟡 ORTA — Directory vehicle_count vs Profile inconsistency

VendorDirectoryProvider::count_active_vehicles_for() counted every publish vehicle, regardless of _mhm_vehicle_lifecycle_status. Profile-side collect_vehicles() filters by lifecycle='active'. So a vendor with 2 active + 3 paused vehicles showed "5 vehicles" on the directory card and "2 vehicles" on the profile page. Marketplace data inconsistency = trust degradation.

Fixed by adding the same meta_query lifecycle filter to the count query.

🐛 Dormant production defect — pagination strict-type TypeError

The new combination tests in this patch surfaced something the existing v4.38.0 tests had never exercised: the directory pagination partial passed $big = 999999999 (int) as the first argument to str_replace(). PHP 8.1+ strict types throw TypeError.

Existing tests never seeded enough vendors to push past per_page=12, so the bug stayed dormant. Production sites running PHP 8.x would have crashed the directory page the moment a 13th active vendor pushed the result set past one page. Cast to string explicitly — same pattern WP core uses in identical callers.

This is the strongest argument for not having shipped v4.38.0 alone.

📌 Phase 5/6/7 paper-cuts

Three small parity fixes that the v4.38.0 audit had pre-documented as deferred:

  • VendorDirectorySeo register guard — early return when an SEO plugin (Yoast / Rank Math / AIOSEO / SEOPress / The SEO Framework / SmartCrawl) owns the contract or the mhm_rentiva_vendor_directory_seo_disable filter is true. Parity with VendorProfileSeo's register guard. Plus a DocBlock spelling out the 3-arg filter signature for build_meta_description($default, $vendor_count, $vehicle_count).
  • VendorDirectoryCacheInvalidator — two parity guards: !is_string($meta_key) short-circuit on the user_meta hooks (rare WP edge case where meta_key arrives as an array — VendorProfileCacheInvalidator already had this guard), and a no-op early-return when $new_status === $old_status on the lifecycle hook (parity with the existing on_comment_status no-op in the same class). Avoids spurious cache flushes that defeat the 30-min directory cache.
  • Pagination/sort combination tests + .current scope — three new tests covering pagination overflow, alpha sort with city filter, and paged query string on page 2. Verifies the .current pagination class stays scoped under .mhm-vendor-directory-pagination so theme .current rules can't hijack the styling.

Pipeline gates

  • PHPUnit: 1044 → 1058 tests, 3289 → 3320 assertions, 7 skipped, 0 fail
  • PHPCS: 0 errors (full project, CI parity gate)
  • Independent code review: merge ready, no KRİTİK/YÜKSEK findings

Deploy notice

Ship v4.38.1 together with the v4.37.0 + v4.37.1 + v4.37.2 + v4.37.3 + v4.38.0 chain — six releases in a single mhmrentiva.com deploy. No separate upgrade path needed.