PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.7.1
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.7.1
1.7.1 1.7.0 1.6.6 1.6.5 1.6.4 1.6.3 1.6.2 1.6.1 1.6.0 1.5.4 1.5.5 1.5.3 1.5.2 1.5.1 1.5.0 1.4.2 1.4.1 1.4.0 1.3.28 1.3.27 1.3.26 1.3.25 1.3.23 1.3.22 1.3.21 All 51 releases
← All changes | app/Services/ProductReviewService.php +89 -0 1.7.0 → 1.7.1 View file →
@@ -1139,8 +1139,38 @@
1139 1139 return max(0, min(5, (int) $value));
1140 1140 }
1141 1141
1142 1142 /**
1143 + * The star ratings a review list is filtered to, from "5,4" or [5, 4].
1144 + *
1145 + * Only whole stars 1-5 survive, each once, so the list is never longer than five.
1146 + *
1147 + * @param string|array $value
1148 + * @return int[]
1149 + */
1150 + public static function ratingList($value): array
1151 + {
1152 + $parts = is_array($value) ? $value : explode(',', (string) $value);
1153 + $ratings = [];
1154 +
1155 + foreach (array_slice($parts, 0, 5) as $part) {
1156 + $part = is_scalar($part) ? trim((string) $part) : '';
1157 +
1158 + if (!ctype_digit($part)) {
1159 + continue;
1160 + }
1161 +
1162 + $rating = (int) $part;
1163 +
1164 + if ($rating >= 1 && $rating <= 5) {
1165 + $ratings[$rating] = $rating;
1166 + }
1167 + }
1168 +
1169 + return array_values($ratings);
1170 + }
1171 +
1172 + /**
1143 1173 * Whether the store collects star ratings at all.
1144 1174 *
1145 1175 * Defaults to on, so a store that has never touched the setting shows the
1146 1176 * rating control.
@@ -1383,8 +1413,67 @@
1383 1413 'reviews' => $reviews->toArray(),
1384 1414 ];
1385 1415
1386 1416 return apply_filters('fluent_cart/review/public_response', $responseData, $postId);
1417 + }
1418 +
1419 + /**
1420 + * Resolve an editorial floor before rendering, or for legacy refreshes.
1421 + * A client id is context only; integrations authenticating their own tokens
1422 + * must verify them before overriding the trusted default.
1423 + */
1424 + public static function resolveListMinRating(string $clientId, int $default = 0, int $postId = 0): int
1425 + {
1426 + $rating = apply_filters('fluent_cart/review/list_min_rating', $default, [
1427 + 'client_id' => $clientId,
1428 + 'post_id' => $postId,
1429 + ]);
1430 +
1431 + return is_numeric($rating) && (int) $rating >= 1 && (int) $rating <= 5
1432 + ? (int) $rating : 0;
1433 + }
1434 +
1435 + /** Product-bound, cache-safe list setting; does not grant access to reviews. */
1436 + public static function listRatingToken(int $postId, int $minimum): string
1437 + {
1438 + $minimum = max(0, min(5, $minimum));
1439 + $payload = 'fcr1-' . $postId . '-' . $minimum;
1440 + $signature = rtrim(strtr(base64_encode(hash_hmac('sha256', $payload, wp_salt('auth'), true)), '+/', '-_'), '=');
1441 + return 'fcr1-' . $minimum . '-' . $signature;
1442 + }
1443 +
1444 + /** Null means absent, modified, or issued for a different product. */
1445 + public static function minRatingFromToken(int $postId, string $token): ?int
1446 + {
1447 + if (!preg_match('/^fcr1-([0-5])-[A-Za-z0-9_-]{43}$/D', $token, $matches)) {
1448 + return null;
1449 + }
1450 + $minimum = (int) $matches[1];
1451 + return hash_equals(static::listRatingToken($postId, $minimum), $token) ? $minimum : null;
1452 + }
1453 +
1454 + /** Shared rating visibility for blocks, shortcodes and addon renderers. */
1455 + public static function ratingMeetsThresholds($product, array $attributes = [], $block = null): bool
1456 + {
1457 + $context = [
1458 + 'product' => $product,
1459 + 'post_id' => (int) $product->ID,
1460 + 'attributes' => $attributes,
1461 + 'block' => $block,
1462 + ];
1463 + $minimumCount = max(0, (int) apply_filters(
1464 + 'fluent_cart/review/min_review_count',
1465 + max(0, (int) Arr::get($attributes, 'minReviewCount', 0)),
1466 + $context
1467 + ));
1468 + $minimumAverage = min(5.0, max(0.0, (float) apply_filters(
1469 + 'fluent_cart/review/min_average_rating',
1470 + min(5.0, max(0.0, (float) Arr::get($attributes, 'minAverageRating', 0))),
1471 + $context
1472 + )));
1473 + $info = $product->detail ? ($product->detail->other_info ?: []) : [];
1474 + return (int) Arr::get($info, 'review_count', 0) >= $minimumCount
1475 + && (float) Arr::get($info, 'average_rating', 0) >= $minimumAverage;
1387 1476 }
1388 1477
1389 1478 /**
1390 1479 * Per-request settings cache, shared by every caller of