{"id":17922702,"url":"https://github.com/overtrue/laravel-favorite","last_synced_at":"2025-05-14T12:10:51.788Z","repository":{"id":43109472,"uuid":"184188307","full_name":"overtrue/laravel-favorite","owner":"overtrue","description":":heart: User favorite feature for Laravel Application.","archived":false,"fork":false,"pushed_at":"2025-03-23T04:57:07.000Z","size":93,"stargazers_count":439,"open_issues_count":2,"forks_count":54,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-13T08:58:42.920Z","etag":null,"topics":["favorites","followers","following","laravel-favorite","user-relations"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/overtrue.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["overtrue"]}},"created_at":"2019-04-30T03:54:26.000Z","updated_at":"2025-03-31T14:20:47.000Z","dependencies_parsed_at":"2024-01-22T01:48:46.833Z","dependency_job_id":"70aacc85-a137-4b32-a4fa-4176db68b1ee","html_url":"https://github.com/overtrue/laravel-favorite","commit_stats":{"total_commits":73,"total_committers":15,"mean_commits":4.866666666666666,"dds":"0.36986301369863017","last_synced_commit":"fe618e80593173a6c54c6c3f6c60f8a87f46aa6a"},"previous_names":[],"tags_count":27,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/overtrue%2Flaravel-favorite","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/overtrue%2Flaravel-favorite/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/overtrue%2Flaravel-favorite/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/overtrue%2Flaravel-favorite/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/overtrue","download_url":"https://codeload.github.com/overtrue/laravel-favorite/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254140760,"owners_count":22021219,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["favorites","followers","following","laravel-favorite","user-relations"],"created_at":"2024-10-28T20:40:30.195Z","updated_at":"2025-05-14T12:10:51.759Z","avatar_url":"https://github.com/overtrue.png","language":"PHP","funding_links":["https://github.com/sponsors/overtrue"],"categories":[],"sub_categories":[],"readme":"## Laravel Favorite\n\n❤️ User favorite feature for Laravel Application.\n\n[![CI](https://github.com/overtrue/laravel-favorite/workflows/CI/badge.svg)](https://github.com/overtrue/laravel-favorite/actions)\n[![Latest Stable Version](https://poser.pugx.org/overtrue/laravel-favorite/v/stable.svg)](https://packagist.org/packages/overtrue/laravel-favorite)\n[![Latest Unstable Version](https://poser.pugx.org/overtrue/laravel-favorite/v/unstable.svg)](https://packagist.org/packages/overtrue/laravel-favorite)\n[![Total Downloads](https://poser.pugx.org/overtrue/laravel-favorite/downloads)](https://packagist.org/packages/overtrue/laravel-favorite)\n[![License](https://poser.pugx.org/overtrue/laravel-favorite/license)](https://packagist.org/packages/overtrue/laravel-favorite)\n\n[![Sponsor me](https://github.com/overtrue/overtrue/blob/master/sponsor-me-button-s.svg?raw=true)](https://github.com/sponsors/overtrue)\n\n## Installing\n\n```shell\ncomposer require overtrue/laravel-favorite -vvv\n```\n\n### Configuration \u0026 Migrations\n\n```php\nphp artisan vendor:publish --provider=\"Overtrue\\LaravelFavorite\\FavoriteServiceProvider\"\n```\n\n## Usage\n\n### Traits\n\n#### `Overtrue\\LaravelFavorite\\Traits\\Favoriter`\n\n```php\n\nuse Illuminate\\Notifications\\Notifiable;\nuse Illuminate\\Contracts\\Auth\\MustVerifyEmail;\nuse Illuminate\\Foundation\\Auth\\User as Authenticatable;\nuse Overtrue\\LaravelFavorite\\Traits\\Favoriter;\n\nclass User extends Authenticatable\n{\n    use Favoriter;\n\n    \u003c...\u003e\n}\n```\n\n#### `Overtrue\\LaravelFavorite\\Traits\\Favoriteable`\n\n```php\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Overtrue\\LaravelFavorite\\Traits\\Favoriteable;\n\nclass Post extends Model\n{\n    use Favoriteable;\n\n    \u003c...\u003e\n}\n```\n\n### API\n\n```php\n$user = User::find(1);\n$post = Post::find(2);\n\n$user-\u003efavorite($post);\n$user-\u003eunfavorite($post);\n$user-\u003etoggleFavorite($post);\n$user-\u003egetFavoriteItems(Post::class)\n\n$user-\u003ehasFavorited($post);\n$post-\u003ehasBeenFavoritedBy($user);\n```\n\n#### Get object favoriters:\n\n```php\nforeach($post-\u003efavoriters as $user) {\n    // echo $user-\u003ename;\n}\n```\n\n#### Get Favorite Model from User.\n\nUsed Favoriter Trait Model can easy to get Favoriteable Models to do what you want.\n_note: this method will return a `Illuminate\\Database\\Eloquent\\Builder` _\n\n```php\n$user-\u003egetFavoriteItems(Post::class);\n\n// Do more\n$favoritePosts = $user-\u003egetFavoriteItems(Post::class)-\u003eget();\n$favoritePosts = $user-\u003egetFavoriteItems(Post::class)-\u003epaginate();\n$favoritePosts = $user-\u003egetFavoriteItems(Post::class)-\u003ewhere('title', 'Laravel-Favorite')-\u003eget();\n```\n\n### Aggregations\n\n```php\n// all\n$user-\u003efavorites()-\u003ecount();\n\n// with type\n$user-\u003efavorites()-\u003ewithType(Post::class)-\u003ecount();\n\n// favoriters count\n$post-\u003efavoriters()-\u003ecount();\n```\n\nList with `*_count` attribute:\n\n```php\n$users = User::withCount('favorites')-\u003eget();\n\nforeach($users as $user) {\n    echo $user-\u003efavorites_count;\n}\n\n\n// for Favoriteable models:\n$posts = Post::withCount('favoriters')-\u003eget();\n\nforeach($posts as $post) {\n    echo $post-\u003efavorites_count;\n}\n```\n\n### Attach user favorite status to favoriteable collection\n\nYou can use `Favoriter::attachFavoriteStatus($favoriteables)` to attach the user favorite status, it will set `has_favorited` attribute to each model of `$favoriteables`:\n\n#### For model\n\n```php\n$post = Post::find(1);\n\n$post = $user-\u003eattachFavoriteStatus($post);\n\n// result\n[\n    \"id\" =\u003e 1\n    \"title\" =\u003e \"Add socialite login support.\"\n    \"created_at\" =\u003e \"2021-05-20T03:26:16.000000Z\"\n    \"updated_at\" =\u003e \"2021-05-20T03:26:16.000000Z\"\n    \"has_favorited\" =\u003e true\n ],\n```\n\n#### For `Collection | Paginator | CursorPaginator | array`:\n\n```php\n$posts = Post::oldest('id')-\u003eget();\n\n$posts = $user-\u003eattachFavoriteStatus($posts);\n\n$posts = $posts-\u003etoArray();\n\n// result\n[\n  [\n    \"id\" =\u003e 1\n    \"title\" =\u003e \"Post title1\"\n    \"created_at\" =\u003e \"2021-05-20T03:26:16.000000Z\"\n    \"updated_at\" =\u003e \"2021-05-20T03:26:16.000000Z\"\n    \"has_favorited\" =\u003e true\n  ],\n  [\n    \"id\" =\u003e 2\n    \"title\" =\u003e \"Post title2\"\n    \"created_at\" =\u003e \"2021-05-20T03:26:16.000000Z\"\n    \"updated_at\" =\u003e \"2021-05-20T03:26:16.000000Z\"\n    \"has_favorited\" =\u003e false\n  ],\n  [\n    \"id\" =\u003e 3\n    \"title\" =\u003e \"Post title3\"\n    \"created_at\" =\u003e \"2021-05-20T03:26:16.000000Z\"\n    \"updated_at\" =\u003e \"2021-05-20T03:26:16.000000Z\"\n    \"has_favorited\" =\u003e true\n  ],\n]\n```\n\n#### For pagination\n\n```php\n$posts = Post::paginate(20);\n\n$user-\u003eattachFavoriteStatus($posts);\n```\n\n### N+1 issue\n\nTo avoid the N+1 issue, you can use eager loading to reduce this operation to just 2 queries. When querying, you may specify which relationships should be eager loaded using the `with` method:\n\n```php\n// Favoriter\n$users = User::with('favorites')-\u003eget();\n\nforeach($users as $user) {\n    $user-\u003ehasFavorited($post);\n}\n\n// with favoriteable object\n$users = User::with('favorites.favoriteable')-\u003eget();\n\nforeach($users as $user) {\n    $user-\u003ehasFavorited($post);\n}\n\n// Favoriteable\n$posts = Post::with('favorites')-\u003eget();\n// or\n$posts = Post::with('favoriters')-\u003eget();\n\nforeach($posts as $post) {\n    $post-\u003eisFavoritedBy($user);\n}\n```\n\n### Events\n\n| **Event**                                     | **Description**                             |\n| --------------------------------------------- | ------------------------------------------- |\n| `Overtrue\\LaravelFavorite\\Events\\Favorited`   | Triggered when the relationship is created. |\n| `Overtrue\\LaravelFavorite\\Events\\Unfavorited` | Triggered when the relationship is deleted. |\n\n## Related packages\n\n-   Follow: [overtrue/laravel-follow](https://github.com/overtrue/laravel-follow)\n-   Like: [overtrue/laravel-like](https://github.com/overtrue/laravel-like)\n-   Favorite: [overtrue/laravel-favorite](https://github.com/overtrue/laravel-favorite)\n-   Subscribe: [overtrue/laravel-subscribe](https://github.com/overtrue/laravel-subscribe)\n-   Vote: [overtrue/laravel-vote](https://github.com/overtrue/laravel-vote)\n-   Bookmark: overtrue/laravel-bookmark (working in progress)\n\n## Contributing\n\nYou can contribute in one of three ways:\n\n1. File bug reports using the [issue tracker](https://github.com/overtrue/laravel-favorite/issues).\n2. Answer questions or fix bugs on the [issue tracker](https://github.com/overtrue/laravel-favorite/issues).\n3. Contribute new features or update the wiki.\n\n_The code contribution process is not very formal. You just need to make sure that you follow the PSR-0, PSR-1, and PSR-2 coding guidelines. Any new code contributions must be accompanied by unit tests where applicable._\n\n## :heart: Sponsor me\n\n[![Sponsor me](https://github.com/overtrue/overtrue/blob/master/sponsor-me.svg?raw=true)](https://github.com/sponsors/overtrue)\n\n如果你喜欢我的项目并想支持它，[点击这里 :heart:](https://github.com/sponsors/overtrue)\n\n## Project supported by JetBrains\n\nMany thanks to Jetbrains for kindly providing a license for me to work on this and other open-source projects.\n\n[![](https://resources.jetbrains.com/storage/products/company/brand/logos/jb_beam.svg)](https://www.jetbrains.com/?from=https://github.com/overtrue)\n\n## PHP 扩展包开发\n\n\u003e 想知道如何从零开始构建 PHP 扩展包？\n\u003e\n\u003e 请关注我的实战课程，我会在此课程中分享一些扩展开发经验 —— [《PHP 扩展包实战教程 - 从入门到发布》](https://learnku.com/courses/creating-package)\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fovertrue%2Flaravel-favorite","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fovertrue%2Flaravel-favorite","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fovertrue%2Flaravel-favorite/lists"}