diff --git a/src/Keys.php b/src/Keys.php index 4a82ec3..6634afc 100755 --- a/src/Keys.php +++ b/src/Keys.php @@ -57,7 +57,7 @@ public function ip($ip) /** * list cache key */ - public function cache($limit = '*', $isLow = false) + public function cache($limit = '*', $isLow = false, $constraints = []) { $key = $this->visits.'_lists'; @@ -65,7 +65,11 @@ public function cache($limit = '*', $isLow = false) return "{$key}:*"; } - return "{$key}:".($isLow ? 'low' : 'top').$limit; + //it might not be that unique but it does the job since not many lists + //will be generated to one key.eloquent + $constraintsPart = count($constraints) ? ':'.substr(sha1(serialize($constraints)), 0, 7) : ''; + + return "{$key}:".($isLow ? 'low' : 'top').$constraintsPart.$limit; } /** diff --git a/src/Traits/Lists.php b/src/Traits/Lists.php index d1e54bd..ed8d27d 100755 --- a/src/Traits/Lists.php +++ b/src/Traits/Lists.php @@ -10,12 +10,18 @@ trait Lists * Fetch all time trending subjects. * * @param int $limit - * @param bool $isLow + * @param array $constraints optional. filter models by attributes (where=[...]) * @return \Illuminate\Support\Collection|array */ - public function top($limit = 5, $orderByAsc = false) + public function top($limit = 5, $orderByAsc = false, $constraints = []) { - $cacheKey = $this->keys->cache($limit, $orderByAsc); + if(is_array($orderByAsc)) { + $constraints = $orderByAsc; + $orderByAsc = false; + } + + $cacheKey = $this->keys->cache($limit, $orderByAsc, $constraints); + $cachedList = $this->cachedList($limit, $cacheKey); $visitsIds = $this->getVisitsIds($limit, $this->keys->visits, $orderByAsc); @@ -23,7 +29,7 @@ public function top($limit = 5, $orderByAsc = false) return $cachedList; } - return $this->freshList($cacheKey, $visitsIds); + return $this->freshList($cacheKey, $visitsIds, $constraints); } @@ -69,11 +75,12 @@ protected function getSortedList($name, $limit, $orderByAsc = false, $withValues * Fetch lowest subjects. * * @param int $limit + * @param array $constraints optional * @return \Illuminate\Support\Collection|array */ - public function low($limit = 5) + public function low($limit = 5, $constraints = []) { - return $this->top($limit, true); + return $this->top($limit, true, $constraints); } @@ -95,13 +102,16 @@ protected function getVisitsIds($limit, $visitsKey, $orderByAsc = false) * @param $visitsIds * @return mixed */ - protected function freshList($cacheKey, $visitsIds) + protected function freshList($cacheKey, $visitsIds, $constraints = []) { if (count($visitsIds)) { $this->connection->delete($cacheKey); return ($this->subject)::whereIn($this->keys->primary, $visitsIds) + ->when(count($constraints), function($query) use($constraints) { + return $query->where($constraints); + }) ->get() ->sortBy(function ($subject) use ($visitsIds) { return array_search($subject->{$this->keys->primary}, $visitsIds); diff --git a/tests/Feature/VisitsTestCase.php b/tests/Feature/VisitsTestCase.php index cb53653..31921d4 100755 --- a/tests/Feature/VisitsTestCase.php +++ b/tests/Feature/VisitsTestCase.php @@ -441,4 +441,19 @@ public function it_list_from_cache() $this->assertNotEquals($fresh2->first(), $cached->first()); } + + /** + * @test + */ + public function it_list_filtered_by_constraints() + { + $posts =[]; + + foreach (['naji', 'fadi', 'hanadi', 'maghi', 'lafi'] as $player) { + $posts[$player] = Post::create(['name' => $player])->fresh(); + visits($posts[$player])->forceIncrement(rand(2, 109)); + } + + $this->assertNotEquals(visits('Awssat\Visits\Tests\Post')->top(5, ['name' => 'naji']), [$posts['naji']]); + } }