1) */ public function blend( LengthAwarePaginator $freshResults, int $perPage = 24, int $page = 1, ): LengthAwarePaginator { // Only blend on page 1; real pagination takes over for deeper pages if (! EarlyGrowth::enabled() || $page > 1) { return $freshResults; } $ratios = EarlyGrowth::blendRatios(); if (($ratios['curated'] + $ratios['spotlight']) < 0.001) { // Mode is effectively "fresh only" — nothing to blend return $freshResults; } $fresh = $freshResults->getCollection(); $freshIds = $fresh->pluck('id')->toArray(); // Calculate absolute item counts from ratios [$freshCount, $curatedCount, $spotlightCount] = $this->allocateCounts($ratios, $perPage); // Fetch sources — over-fetch to account for deduplication losses $curated = $this->spotlight ->getCurated($curatedCount + 6) ->filter(fn ($a) => ! in_array($a->id, $freshIds, true)) ->take($curatedCount) ->values(); $curatedIds = $curated->pluck('id')->toArray(); $spotlightItems = $this->spotlight ->getSpotlight($spotlightCount + 6) ->filter(fn ($a) => ! in_array($a->id, $freshIds, true)) ->filter(fn ($a) => ! in_array($a->id, $curatedIds, true)) ->take($spotlightCount) ->values(); // Compose blended page $blended = $fresh->take($freshCount) ->concat($curated) ->concat($spotlightItems) ->unique('id') ->values(); // Pad back to $perPage with leftover fresh items if any source ran short if ($blended->count() < $perPage) { $usedIds = $blended->pluck('id')->toArray(); $pad = $fresh ->filter(fn ($a) => ! in_array($a->id, $usedIds, true)) ->take($perPage - $blended->count()); $blended = $blended->concat($pad)->unique('id')->values(); } // Rebuild paginator preserving the real total so pagination links remain stable return new LengthAwarePaginator( $blended->take($perPage)->all(), $freshResults->total(), // ← real total, not blended count $perPage, $page, [ 'path' => $freshResults->path(), 'pageName' => $freshResults->getPageName(), ] ); } // ─── Private helpers ───────────────────────────────────────────────────── /** * Distribute $perPage slots across fresh / curated / spotlight. * Returns [freshCount, curatedCount, spotlightCount]. */ private function allocateCounts(array $ratios, int $perPage): array { $total = max(0.001, ($ratios['fresh'] ?? 0) + ($ratios['curated'] ?? 0) + ($ratios['spotlight'] ?? 0)); $freshN = (int) round($perPage * ($ratios['fresh'] ?? 1.0) / $total); $curatedN = (int) round($perPage * ($ratios['curated'] ?? 0.0) / $total); $spotN = $perPage - $freshN - $curatedN; return [max(0, $freshN), max(0, $curatedN), max(0, $spotN)]; } }