Skip to main content

Rentiva v4.37.1 — Vendor profile hotfix

· 5 min read
MaxHandMade
Maintainer

Three smoke-test findings on the freshly-shipped v4.37.0 vendor profile page are closed in v4.37.1: a badge that defaulted to "New Vendor" for every vendor regardless of their score, a misleading "X reviews" label whose number was actually the count of booking-time star ratings, and review stars that disappeared on the public profile when reviews were imported from third-party plugins.

Why a hotfix on the same day

v4.37.0 shipped this morning with a Pro feature spread across nine implementation phases and 78 new tests. PHPUnit was green, PHPCS was clean, the dispatch path worked end to end. But three of the bugs that made it into production were the kind that a unit test cannot easily catch:

  • A wiring bug — registration in the wrong init bucket — that a test fixture papers over by adding the filter callback explicitly.
  • A semantic bug — the wrong word in a translatable string — that no machine-readable check flags.
  • A defensive gap — only checking the canonical meta key, not the WC-standard alternative — that bites the day a third-party plugin imports a review.

Browser smoke surfaced all three within minutes of seeding three test vendors. The fix matrix is small enough that a same-day patch is the right call.

B1 — Badge stuck on "New Vendor"

The badge evaluator checks three thresholds: account age, reliability score, and lifetime completed bookings. The completed-bookings count comes from a filter:

$completed = (int) apply_filters(
'mhm_rentiva_vendor_completed_bookings_count',
0, // default
$user_id
);

The production callback for that filter is registered in VendorProfileExtension::register(), which Plugin.php calls from initialize_admin_services() — the admin-only init bucket. On public requests (is_admin() === false), the bucket never runs and the callback never registers, so the count defaults to 0. Every vendor falls into the STATUS_NEW branch, no matter their actual booking history.

This is the same is_admin() bucket trap we surfaced in Phase 9 — VendorProfileSchema::register() was originally placed in the admin-only bucket and got moved to a context-agnostic bucket once browser smoke caught the absent JSON-LD. VendorProfileExtension::register() legitimately belongs in the admin bucket (it owns admin-only profile screen hooks), but its filter-callback side effect leaked the bug into the frontend.

The fix is to make the badge work without depending on that wiring at all:

$default_completed = class_exists(ReliabilityScoreCalculator::class)
? ReliabilityScoreCalculator::count_completed_bookings($user_id, 9999)
: 0;

$completed = (int) apply_filters(
'mhm_rentiva_vendor_completed_bookings_count',
$default_completed,
$user_id
);

Filter callbacks can still override the count for special cases (lifecycle penalty suppressions, manual admin overrides, etc.). The default is now a real number, not a placeholder waiting for someone to wire it up.

B2 — Hero label "X reviews" was the wrong word

The vendor profile hero shows aggregate rating data:

★★★★½ 4,8 ( 25 değerlendirme )

That 25 is the sum of _mhm_rentiva_rating_count across the vendor's active vehicles — booking-time star ratings, set when a customer completes a rental and rates the vehicle. The Recent Reviews section below the hero is a separate stream — WP review comments on the same vehicle posts. A vendor can easily have 25 booking ratings and 4 written review comments. The hero said "25 reviews", the section showed 4, and the math didn't add up.

The fix is the easy half of the problem: change the i18n string from %d review / %d reviews to %d rating / %d ratings (Turkish: %d değerlendirme). Same number, honest label.

The harder version of this question — should the hero show the WP comment count instead of the booking-rating count? — is deferred. The booking-rating average is the more useful metric for buyers because it's tied to completed transactions, not opinions. Renaming the label preserves that information.

B3 — Review stars empty for third-party imports

VendorProfileProvider::collect_reviews() builds the per-review render data:

'rating' => (int) get_comment_meta($comment_id, 'mhm_rating', true),

mhm_rating is Rentiva's canonical key, set by VehicleRatingForm and the ReviewEnforcer normalization hook. Reviews submitted through Rentiva's own form get this key reliably. But a vendor whose reviews are imported from a third-party plugin — WC product reviews migrated into vehicles, Site Reviews / Customer Reviews for WooCommerce, manual database seeds — typically writes the WC-standard rating key. Without a fallback, those reviews show up on the profile with empty stars even though the rating value is right there in the database.

The fix is a one-helper change:

private static function resolve_review_rating(int $comment_id): int
{
$rating = (int) get_comment_meta($comment_id, 'mhm_rating', true);
if ($rating > 0) {
return $rating;
}
return (int) get_comment_meta($comment_id, 'rating', true);
}

Canonical wins when present; WC-standard falls through when it doesn't.

Validation

Three test vendors, seeded directly into the local DB:

VendorScoreBookingsApprovedExpectedGot
Akif Yıldız9220200 days agoVerified✓ Doğrulanmış Bayi
Zeynep Demir8811335 days agoVerified✓ Doğrulanmış Bayi
Mehmet Çelik45221 days agoNewYeni Bayi

All three render star ratings on every review item; the hero label reads X değerlendirme (TR) / X ratings (EN).

PHPUnit went from 982 → 987 with the two new regression test classes (VendorBadgeDefaultFallbackTest 2 tests, VendorProfileReviewRatingFallbackTest 3 tests). The badge fallback test deliberately omits the filter callback registration so it would have failed against v4.37.0.