| @@ -31,8 +31,19 @@ | ||
| 31 | 31 | public const PAYMENT_AUTHORIZED = 'authorized'; |
| 32 | 32 | public const PAYMENT_SCHEDULED = 'payment_scheduled'; |
| 33 | 33 | |
| 34 | 34 | // Transaction Statuses |
| 35 | + // Product review statuses — fct_product_reviews.status values | |
| 36 | + public const REVIEW_APPROVED = 'approved'; | |
| 37 | + public const REVIEW_PENDING = 'pending'; | |
| 38 | + public const REVIEW_SPAM = 'spam'; | |
| 39 | + public const REVIEW_TRASH = 'trash'; | |
| 40 | + | |
| 41 | + // Review permission modes — who may submit a review | |
| 42 | + public const REVIEW_PERMISSION_VERIFIED_BUYERS = 'verified_buyers'; | |
| 43 | + public const REVIEW_PERMISSION_LOGGED_IN = 'logged_in'; | |
| 44 | + public const REVIEW_PERMISSION_ANYONE = 'anyone'; | |
| 45 | + | |
| 35 | 46 | public const TRANSACTION_SUCCEEDED = 'succeeded'; |
| 36 | 47 | public const TRANSACTION_AUTHORIZED = 'authorized'; |
| 37 | 48 | public const TRANSACTION_PENDING = 'pending'; |
| 38 | 49 | public const TRANSACTION_REFUNDED = 'refunded'; |
| @@ -348,8 +359,61 @@ | ||
| 348 | 359 | |
| 349 | 360 | public static function getTransactionSuccessStatuses() |
| 350 | 361 | { |
| 351 | 362 | return apply_filters('fluent_cart/transaction_success_statuses', [self::TRANSACTION_SUCCEEDED, self::TRANSACTION_AUTHORIZED], []); |
| 363 | + } | |
| 364 | + | |
| 365 | + /** | |
| 366 | + * All product review statuses (fct_product_reviews.status values). | |
| 367 | + */ | |
| 368 | + public static function getReviewStatuses(): array | |
| 369 | + { | |
| 370 | + return [ | |
| 371 | + self::REVIEW_APPROVED, | |
| 372 | + self::REVIEW_PENDING, | |
| 373 | + self::REVIEW_SPAM, | |
| 374 | + self::REVIEW_TRASH, | |
| 375 | + ]; | |
| 376 | + } | |
| 377 | + | |
| 378 | + /** | |
| 379 | + * Review statuses that count as an existing review for duplicate | |
| 380 | + * detection. Spam and trash are deliberately excluded — a review the | |
| 381 | + * store rejected does not block the customer from submitting a fresh | |
| 382 | + * one. Every surface that projects "can this user review?" must use | |
| 383 | + * this set so it never contradicts the | |
| 384 | + * ProductReviewService::canSubmitReview() write-path guard. | |
| 385 | + */ | |
| 386 | + public static function getReviewDuplicateStatuses(): array | |
| 387 | + { | |
| 388 | + return apply_filters('fluent_cart/review_duplicate_statuses', [ | |
| 389 | + self::REVIEW_APPROVED, | |
| 390 | + self::REVIEW_PENDING, | |
| 391 | + ]); | |
| 392 | + } | |
| 393 | + | |
| 394 | + /** | |
| 395 | + * Review statuses the author may see in their own history: everything | |
| 396 | + * except spam and trash. | |
| 397 | + * | |
| 398 | + * Derived by exclusion, not by listing, so a status added later is | |
| 399 | + * visible to its author by default — only the two that mean "this is not | |
| 400 | + * really a review" are held back, and a customer who has been silently | |
| 401 | + * spammed or trashed is not shown that judgement. | |
| 402 | + * | |
| 403 | + * Deliberately NOT getReviewDuplicateStatuses(). The two sets happen to | |
| 404 | + * hold the same values today, but they answer different questions, and | |
| 405 | + * that one is filterable: a site narrowing its duplicate rules would | |
| 406 | + * otherwise hide customers' pending reviews from them as a side effect. | |
| 407 | + * | |
| 408 | + * @return array | |
| 409 | + */ | |
| 410 | + public static function getReviewAuthorVisibleStatuses(): array | |
| 411 | + { | |
| 412 | + return array_values(array_diff( | |
| 413 | + static::getReviewStatuses(), | |
| 414 | + [self::REVIEW_SPAM, self::REVIEW_TRASH] | |
| 415 | + )); | |
| 352 | 416 | } |
| 353 | 417 | |
| 354 | 418 | // Get all statuses (optional utility) |
| 355 | 419 | public static function all() |