37 lines
1.4 KiB
PHP
37 lines
1.4 KiB
PHP
<?php
|
|
|
|
namespace Modules\Core\Catalog\Recommendations;
|
|
|
|
use Illuminate\Support\Collection;
|
|
use Lunar\Facades\ModelManifest;
|
|
use Lunar\Models\Contracts\Product as ProductContract;
|
|
use Lunar\Models\Product;
|
|
use Modules\Core\Catalog\Contracts\RecommendationRule;
|
|
|
|
/**
|
|
* The universal fallback — always returns something as long as the store
|
|
* has more than one product, since it has no eligibility condition of its
|
|
* own to come up empty on. Meant to be placed last in
|
|
* config('catalog.recommendation_rules'), not first: every store using
|
|
* the default chain gets a real fallback, but one that only kicks in once
|
|
* more specific rules (same category, same tag, ...) have had a chance.
|
|
*/
|
|
class RandomRule implements RecommendationRule
|
|
{
|
|
public function recommend(Product $product, int $limit, array $exclude): Collection
|
|
{
|
|
// ModelManifest::get(), not Product::query() directly — the base
|
|
// Lunar\Models\Product has no custom_fields cast/fillable entry
|
|
// (see Catalog\Models\Product's own docblock), so a recommendation
|
|
// resolved as the base class silently lost that field once
|
|
// ProductIndexer started reading it for recommendations.has_custom_fields.
|
|
$model = ModelManifest::get(ProductContract::class);
|
|
|
|
return $model::query()
|
|
->whereKeyNot($exclude)
|
|
->inRandomOrder()
|
|
->limit($limit)
|
|
->get();
|
|
}
|
|
}
|