Skip to content

Commit

Permalink
fix: Fixed error commit #34
Browse files Browse the repository at this point in the history
  • Loading branch information
overtrue committed Dec 8, 2022
1 parent 804751c commit 7f79ca0
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 108 deletions.
48 changes: 0 additions & 48 deletions .php-cs-fixer.php

This file was deleted.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ $post = $user->attachFavoriteStatus($post);
],
```

#### For `Collection | Paginator | LengthAwarePaginator | array`:
#### For `Collection | Paginator | CursorPaginator | array`:

```php
$posts = Post::oldest('id')->get();
Expand Down
9 changes: 5 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@
"mockery/mockery": "^1.4.4",
"phpunit/phpunit": "^9.5.10",
"orchestra/testbench": "^7.0",
"brainmaestro/composer-git-hooks": "^2.8",
"friendsofphp/php-cs-fixer": "^3.5"
"friendsofphp/php-cs-fixer": "^3.5",
"brainmaestro/composer-git-hooks": "dev-master",
"laravel/pint": "^1.2"
},
"extra": {
"laravel": {
Expand Down Expand Up @@ -57,8 +58,8 @@
"cghooks update"
],
"cghooks": "vendor/bin/cghooks",
"check-style": "php-cs-fixer fix --using-cache=no --diff --dry-run --ansi",
"fix-style": "php-cs-fixer fix --using-cache=no --ansi",
"check-style": "vendor/bin/pint --test",
"fix-style": "vendor/bin/pint",
"test": "vendor/bin/phpunit --colors=always"
},
"scripts-descriptions": {
Expand Down
8 changes: 4 additions & 4 deletions src/FavoriteServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,22 @@ class FavoriteServiceProvider extends ServiceProvider
public function boot()
{
$this->publishes([
\dirname(__DIR__) . '/config/favorite.php' => config_path('favorite.php'),
\dirname(__DIR__).'/config/favorite.php' => config_path('favorite.php'),
], 'favorite-config');

$this->publishes([
\dirname(__DIR__) . '/migrations/' => database_path('migrations'),
\dirname(__DIR__).'/migrations/' => database_path('migrations'),
], 'favorite-migrations');

if ($this->app->runningInConsole()) {
$this->loadMigrationsFrom(\dirname(__DIR__) . '/migrations/');
$this->loadMigrationsFrom(\dirname(__DIR__).'/migrations/');
}
}

public function register()
{
$this->mergeConfigFrom(
\dirname(__DIR__) . '/config/favorite.php',
\dirname(__DIR__).'/config/favorite.php',
'favorite'
);
}
Expand Down
75 changes: 33 additions & 42 deletions src/Traits/Favoriter.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@

namespace Overtrue\LaravelFavorite\Traits;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Contracts\Pagination\CursorPaginator;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Contracts\Pagination\Paginator;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Pagination\AbstractCursorPaginator;
use Illuminate\Pagination\AbstractPaginator;
use Illuminate\Support\Collection;
use Illuminate\Support\Enumerable;
use Illuminate\Support\LazyCollection;

/**
Expand All @@ -18,8 +16,8 @@ trait Favoriter
{
public function favorite(Model $object): void
{
/* @var \Overtrue\LaravelFavorite\Traits\Favoriteable $object */
if (!$this->hasFavorited($object)) {
/* @var \Overtrue\LaravelFavorite\Traits\Favoriteable|Model $object */
if (! $this->hasFavorited($object)) {
$favorite = app(config('favorite.favorite_model'));
$favorite->{config('favorite.user_foreign_key')} = $this->getKey();

Expand Down Expand Up @@ -59,52 +57,45 @@ public function favorites(): \Illuminate\Database\Eloquent\Relations\HasMany
return $this->hasMany(config('favorite.favorite_model'), config('favorite.user_foreign_key'), $this->getKeyName());
}

public function attachFavoriteStatus($favoriteables, callable $resolver = null)
public function attachFavoriteStatus(&$favoriteables, callable $resolver = null)
{
$returnFirst = false;
$toArray = false;

switch (true) {
case $favoriteables instanceof Model:
$returnFirst = true;
$favoriteables = \collect([$favoriteables]);
break;
case $favoriteables instanceof LengthAwarePaginator:
$favoriteables = $favoriteables->getCollection();
break;
case $favoriteables instanceof Paginator:
case $favoriteables instanceof CursorPaginator:
$favoriteables = \collect($favoriteables->items());
break;
case $favoriteables instanceof LazyCollection:
$favoriteables = \collect($favoriteables->all());
break;
case \is_array($favoriteables):
$favoriteables = \collect($favoriteables);
$toArray = true;
break;
}

\abort_if(!($favoriteables instanceof Enumerable), 422, 'Invalid $favoriteables type.');

$favorited = $this->favorites()->get()->keyBy(function ($item) {
return \sprintf('%s:%s', $item->favoriteable_type, $item->favoriteable_id);
$favorites = $this->favorites()->get()->keyBy(function ($item) {
return \sprintf('%s-%s', $item->favoriteable_type, $item->favoriteable_id);
});

$favoriteables->map(function ($favoriteable) use ($favorited, $resolver) {
$attachStatus = function ($favoriteable) use ($favorites, $resolver) {
$resolver = $resolver ?? fn ($m) => $m;
$favoriteable = $resolver($favoriteable);

if ($favoriteable && \in_array(Favoriteable::class, \class_uses_recursive($favoriteable))) {
$key = \sprintf('%s:%s', $favoriteable->getMorphClass(), $favoriteable->getKey());
$favoriteable->setAttribute('has_favorited', $favorited->has($key));
if (\in_array(Favoriteable::class, \class_uses($favoriteable))) {
$key = \sprintf('%s-%s', $favoriteable->getMorphClass(), $favoriteable->getKey());
$favoriteable->setAttribute('has_favorited', $favorites->has($key));
}
});

return $returnFirst ? $favoriteables->first() : ($toArray ? $favoriteables->all() : $favoriteables);
return $favoriteable;
};

switch (true) {
case $favoriteables instanceof Model:
return $attachStatus($favoriteables);
case $favoriteables instanceof Collection:
return $favoriteables->each($attachStatus);
case $favoriteables instanceof LazyCollection:
return $favoriteables = $favoriteables->map($attachStatus);
case $favoriteables instanceof AbstractPaginator:
case $favoriteables instanceof AbstractCursorPaginator:
return $favoriteables->through($attachStatus);
case $favoriteables instanceof Paginator:
// custom paginator will return a collection
return collect($favoriteables->items())->transform($attachStatus);
case \is_array($favoriteables):
return \collect($favoriteables)->transform($attachStatus);
default:
throw new \InvalidArgumentException('Invalid argument type.');
}
}

public function getFavoriteItems(string $model): Builder
public function getFavoriteItems(string $model)
{
return app($model)->whereHas(
'favoriters',
Expand Down
47 changes: 41 additions & 6 deletions tests/FeatureTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -185,16 +185,52 @@ public function test_favoriter_can_attach_favorite_status_to_votable_collection(
$user->favorite($post1);
$user->favorite($post2);

// collection
// Model
$post1->refresh();
$this->assertNull($post1['has_favorited']);

$user->attachFavoriteStatus($post1);
$this->assertTrue($post1['has_favorited']);

// Collection
$posts = Post::oldest('id')->get();
$this->assertSame($posts, $user->attachFavoriteStatus($posts));
$this->assertTrue($posts[0]['has_favorited']);
$this->assertTrue($posts[1]['has_favorited']);
$this->assertFalse($posts[2]['has_favorited']);

// LazyCollection
$posts = Post::oldest('id')->cursor();
$user->attachFavoriteStatus($posts);
$posts = $posts->toArray();
$this->assertTrue($posts[0]['has_favorited']);
$this->assertTrue($posts[1]['has_favorited']);
$this->assertFalse($posts[2]['has_favorited']);

// user has up favorited post1
// Paginator
$posts = Post::oldest('id')->paginate(20);
$postsWithFavoriteStatus = $user->attachFavoriteStatus($posts);
$this->assertSame($posts, $postsWithFavoriteStatus);
$this->assertTrue($posts[0]['has_favorited']);
// user has down favorited post2
$this->assertTrue($posts[1]['has_favorited']);
// user hasn't favorited post3
$this->assertFalse($posts[2]['has_favorited']);

// https://github.com/overtrue/laravel-favorite/issues/33
$this->assertTrue(method_exists($postsWithFavoriteStatus, 'links'));

// cursor paginator
$posts = Post::oldest('id')->cursorPaginate(20);
$this->assertSame($posts, $user->attachFavoriteStatus($posts));
$this->assertTrue($posts[0]['has_favorited']);
$this->assertTrue($posts[1]['has_favorited']);
$this->assertFalse($posts[2]['has_favorited']);

// array
$posts = Post::oldest('id')->get()->all();
$posts = $user->attachFavoriteStatus($posts);
$this->assertTrue($posts[0]['has_favorited']);
$this->assertTrue($posts[1]['has_favorited']);

$this->assertFalse($posts[2]['has_favorited']);

// paginator
Expand Down Expand Up @@ -227,7 +263,7 @@ public function test_favoriter_can_attach_favorite_status_to_votable_collection(
// custom resolver
$posts = [['post' => $post1], ['post' => $post2], ['post' => $post3]];

$posts = $user->attachFavoriteStatus($posts, fn ($i) => $i['post']);
$user->attachFavoriteStatus($posts, fn ($i) => $i['post']);

// user has up favorited post1
$this->assertTrue($posts[0]['post']['has_favorited']);
Expand Down Expand Up @@ -257,7 +293,6 @@ public function test_has_favorited()
$this->assertDatabaseCount('favorites', 0);
}


protected function getQueryLog(\Closure $callback): \Illuminate\Support\Collection
{
$sqls = \collect([]);
Expand Down
5 changes: 2 additions & 3 deletions tests/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ abstract class TestCase extends \Orchestra\Testbench\TestCase
/**
* Load package service provider.
*
* @param \Illuminate\Foundation\Application $app
*
* @param \Illuminate\Foundation\Application $app
* @return array
*/
protected function getPackageProviders($app)
Expand All @@ -21,7 +20,7 @@ protected function getPackageProviders($app)
/**
* Define environment setup.
*
* @param \Illuminate\Foundation\Application $app
* @param \Illuminate\Foundation\Application $app
*/
protected function getEnvironmentSetUp($app)
{
Expand Down

0 comments on commit 7f79ca0

Please sign in to comment.