alyakin / favorites
Favorites system for Laravel with folder support and polymorphic relations
Requires
- php: ^8.1
- illuminate/support: ^10.0
Requires (Dev)
- orchestra/testbench: ^8.0
README
π¦ ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅
Laravel Favorites
β ΡΡΠΎ ΡΠ½ΠΈΠ²Π΅ΡΡΠ°Π»ΡΠ½ΡΠΉ ΠΌΠΎΠ΄ΡΠ»Ρ Π΄Π»Ρ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΠΏΠΎΠ»ΠΈΠΌΠΎΡΡΠ½ΡΡ
ΡΠ²ΡΠ·Π΅ΠΉ ΠΌΠ΅ΠΆΠ΄Ρ Π²Π»Π°Π΄Π΅Π»ΡΡΠ΅ΠΌ ΠΈ Π»ΡΠ±ΡΠΌΠΈ ΠΈΠ·Π±ΠΈΡΠ°Π΅ΠΌΡΠΌΠΈ ΡΡΡΠ½ΠΎΡΡΡΠΌΠΈ.
ΠΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΠΎΠ΄Π½ΠΎΠΌΡ Π²Π»Π°Π΄Π΅Π»ΡΡΡ (ΠΏΡΠΎΡΠΈΠ»Ρ, ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ ΠΈ Ρ.ΠΏ.) Π΄ΠΎΠ±Π°Π²Π»ΡΡΡ Π² ΠΈΠ·Π±ΡΠ°Π½Π½ΠΎΠ΅ ΠΎΠ±ΡΠ΅ΠΊΡΡ ΡΠ°Π·Π½ΡΡ
ΠΌΠΎΠ΄Π΅Π»Π΅ΠΉ, ΡΠ°ΠΊΠΈΡ
ΠΊΠ°ΠΊ ΡΠΎΠ²Π°ΡΡ, ΡΡΠ°ΡΡΠΈ, ΠΏΡΠΎΡΠΈΠ»ΠΈ, ΠΊΠΎΠΌΠΌΠ΅Π½ΡΠ°ΡΠΈΠΈ ΠΈ Π΄Ρ.
ΠΠ°ΠΊΠ΅Ρ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅Ρ:
- ΠΎΡΠ³Π°Π½ΠΈΠ·Π°ΡΠΈΡ ΠΈΠ·Π±ΡΠ°Π½Π½ΠΎΠ³ΠΎ ΠΏΠΎ ΠΏΠ°ΠΏΠΊΠ°ΠΌ Ρ ΡΠ½ΠΈΠΊΠ°Π»ΡΠ½ΡΠΌΠΈ Π½Π°Π·Π²Π°Π½ΠΈΡΠΌΠΈ,
- ΡΠ°Π±ΠΎΡΡ Ρ UUID ΠΈ timestamps "ΠΈΠ· ΠΊΠΎΡΠΎΠ±ΠΊΠΈ",
- ΡΡΡΠΎΠ³ΡΡ ΠΏΡΠΈΠ²ΡΠ·ΠΊΡ ΠΈΠ·Π±ΡΠ°Π½Π½ΠΎΠ³ΠΎ ΠΊ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΠΎΠΌΡ Π²Π»Π°Π΄Π΅Π»ΡΡΡ.
π― ΠΠΎΠ΄Ρ ΠΎΠ΄ΠΈΡ Π΄Π»Ρ
- πΌ ΠΠ»Π΅ΠΊΡΡΠΎΠ½Π½ΠΎΠΉ ΠΊΠΎΠΌΠΌΠ΅ΡΡΠΈΠΈ β ΠΏΠΎΠΊΡΠΏΠ°ΡΠ΅Π»Ρ ΠΌΠΎΠΆΠ΅Ρ ΡΠΎΡ ΡΠ°Π½ΡΡΡ ΠΈΠ·Π±ΡΠ°Π½Π½ΡΠ΅ ΡΠΎΠ²Π°ΡΡ, Π±ΡΠ΅Π½Π΄Ρ ΠΈΠ»ΠΈ ΠΏΠΎΠ΄Π±ΠΎΡΠΊΠΈ.
- π ΠΠΎΠ½ΡΠ΅Π½Ρ-ΠΏΠ»Π°ΡΡΠΎΡΠΌ β ΡΠΈΡΠ°ΡΠ΅Π»Ρ ΠΌΠΎΠΆΠ΅Ρ Π΄ΠΎΠ±Π°Π²Π»ΡΡΡ Π² ΠΈΠ·Π±ΡΠ°Π½Π½ΠΎΠ΅ ΡΡΠ°ΡΡΠΈ, Π°Π²ΡΠΎΡΠΎΠ² ΠΈΠ»ΠΈ Ρ Π΅ΡΡΠ΅Π³ΠΈ.
- π B2B/CRM ΡΠΈΡΡΠ΅ΠΌ β ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ ΠΌΠΎΠΆΠ΅Ρ Π³ΡΡΠΏΠΏΠΈΡΠΎΠ²Π°ΡΡ ΠΊΠ»ΠΈΠ΅Π½ΡΠΎΠ², Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΡ ΠΈΠ»ΠΈ ΡΠ΄Π΅Π»ΠΊΠΈ Π² "ΠΈΠ·Π±ΡΠ°Π½Π½ΠΎΠ΅" Π΄Π»Ρ Π±ΡΡΡΡΠΎΠ³ΠΎ Π΄ΠΎΡΡΡΠΏΠ°.
π§ ΠΠ³Π»Π°Π²Π»Π΅Π½ΠΈΠ΅
- Π‘ΠΈΡΡΠ΅ΠΌΠ½ΡΠ΅ ΡΡΠ΅Π±ΠΎΠ²Π°Π½ΠΈΡ
- Π£ΡΡΠ°Π½ΠΎΠ²ΠΊΠ°
- ΠΠ°ΠΊ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ
- ΠΠ°ΡΡΠΎΠΌΠΈΠ·Π°ΡΠΈΡ
- π€ Π‘ΠΎΡΡΡΠ΄Π½ΠΈΡΠ΅ΡΡΠ²ΠΎ
- π ΠΠΈΡΠ΅Π½Π·ΠΈΡ
π Π‘ΠΈΡΡΠ΅ΠΌΠ½ΡΠ΅ ΡΡΠ΅Π±ΠΎΠ²Π°Π½ΠΈΡ
- PHP 8.1 ΠΈΠ»ΠΈ Π²ΡΡΠ΅
- Laravel 10.x ΠΈΠ»ΠΈ Π²ΡΡΠ΅
- Composer Π΄Π»Ρ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΡΠΌΠΈ
π₯ Π£ΡΡΠ°Π½ΠΎΠ²ΠΊΠ°
Π£ΡΡΠ°Π½ΠΎΠ²ΠΈΡΠ΅ ΠΏΠ°ΠΊΠ΅Ρ ΡΠ΅ΡΠ΅Π· Composer:
composer require alyakin/favorites
Π€Π°ΠΉΠ» ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ ΠΎΡΡΡΡΡΡΠ²ΡΠ΅Ρ β ΠΌΠΎΠ΄ΡΠ»Ρ Π³ΠΎΡΠΎΠ² ΠΊ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ ΡΡΠ°Π·Ρ ΠΏΠΎΡΠ»Π΅ ΡΡΡΠ°Π½ΠΎΠ²ΠΊΠΈ ΠΈ ΡΠ΅Π³ΠΈΡΡΡΠ°ΡΠΈΠΈ ΠΏΡΠΎΠ²Π°ΠΉΠ΄Π΅ΡΠ°.
βοΈ ΠΠ°ΠΊ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ
Π‘Π΅ΡΠ²ΠΈΡΡ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ»ΡΡΠΈΡΡ ΡΠ΅ΡΠ΅Π· ΡΠ΅ΡΠ²ΠΈΡ-ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ Laravel:
use \Alyakin\Favorites\Services\{FavoriteService, FavoriteFolderService}; $favoritesService = app(FavoriteService::class); $folderService = app(FavoriteFolderService::class);
ΠΠΈΠΆΠ΅ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½Ρ Π±Π°Π·ΠΎΠ²ΡΠ΅ ΡΡΠ΅Π½Π°ΡΠΈΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ.
β ΠΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ Π² ΠΈΠ·Π±ΡΠ°Π½Π½ΠΎΠ΅
// ΠΠΎΠ±Π°Π²ΠΈΡΡ ΠΎΠ±ΡΠ΅ΠΊΡ Π² ΠΈΠ·Π±ΡΠ°Π½Π½ΠΎΠ΅ $favoritesService->addToFavorites($ownerId, $model); // ΠΠΎΠ±Π°Π²ΠΈΡΡ Π² ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΡΡ ΠΏΠ°ΠΏΠΊΡ: $favoritesService->addToFavorites($ownerId, $model, 'read later');
β Π£Π΄Π°Π»Π΅Π½ΠΈΠ΅ ΠΈΠ· ΠΈΠ·Π±ΡΠ°Π½Π½ΠΎΠ³ΠΎ
// Π£Π΄Π°Π»ΠΈΡΡ ΠΎΠ±ΡΠ΅ΠΊΡ ΠΈΠ· ΠΈΠ·Π±ΡΠ°Π½Π½ΠΎΠ³ΠΎ: $favoritesService->removeFromFavorites($ownerId, $model);
π Π Π°Π±ΠΎΡΠ° Ρ ΠΏΠ°ΠΏΠΊΠ°ΠΌΠΈ
// Π‘ΠΎΠ·Π΄Π°ΡΡ ΠΏΠ°ΠΏΠΊΡ $folderService->createFolder($ownerId, 'ΠΠ°ΠΏΠΊΠ°'); // ΠΠ΅ΡΠ΅ΠΈΠΌΠ΅Π½ΠΎΠ²Π°ΡΡ ΠΏΠ°ΠΏΠΊΡ $folderService->renameFolder($ownerId, $folderId, $newName); // ΠΠ΅ΡΠ΅ΠΌΠ΅ΡΡΠΈΡΡ ΡΠ»Π΅ΠΌΠ΅Π½Ρ Π² ΠΏΠ°ΠΏΠΊΡ: $favoritesService->moveToFolder($favoriteId, $folderId); // ΠΠΎΠ»ΡΡΠΈΡΡ Π²ΡΠ΅ ΠΏΠ°ΠΏΠΊΠΈ Π²Π»Π°Π΄Π΅Π»ΡΡΠ°: $folderService->getAllFoldersForOwner($ownerId); // Π£Π΄Π°Π»ΠΈΡΡ ΠΏΠ°ΠΏΠΊΡ: // β οΈ ΠΠΠΠΠΠΠΠ! ΠΡΠΈ ΡΠ΄Π°Π»Π΅Π½ΠΈΠΈ ΠΏΠ°ΠΏΠΊΠΈ Π±ΡΠ΄ΡΡ ΡΠ°ΠΊΠΆΠ΅ ΡΠ΄Π°Π»Π΅Π½Ρ Π²ΡΠ΅ ΠΈΠ·Π±ΡΠ°Π½Π½ΡΠ΅ ΡΠ»Π΅ΠΌΠ΅Π½ΡΡ Π²Π½ΡΡΡΠΈ Π½Π΅Ρ. $folderService->deleteFolder($ownerId, $folderId);
π ΠΠΎΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΠΈΠ·Π±ΡΠ°Π½Π½ΠΎΠ³ΠΎ
// ΠΠΎΠ»ΡΡΠΈΡΡ Π²ΡΠ΅ ΠΈΠ·Π±ΡΠ°Π½Π½ΡΠ΅ ΡΠ»Π΅ΠΌΠ΅Π½ΡΡ Π²Π»Π°Π΄Π΅Π»ΡΡΠ°: $favoritesService->getFavorites($ownerId); // ΠΠΎΠ»ΡΡΠΈΡΡ ΠΈΠ·Π±ΡΠ°Π½Π½ΡΠ΅ Π² ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΠΎΠΉ ΠΏΠ°ΠΏΠΊΠ΅: $favoritesService->getFavorites($ownerId, 'funy'); // ΠΡΠΎΠ²Π΅ΡΠΈΡΡ, Π½Π°Ρ ΠΎΠ΄ΠΈΡΡΡ Π»ΠΈ ΠΎΠ±ΡΠ΅ΠΊΡ Π² ΠΈΠ·Π±ΡΠ°Π½Π½ΠΎΠΌ: $favoritesService->isFavorited($ownerId, $model);
π ΠΠ°ΡΡΠΎΠΌΠΈΠ·Π°ΡΠΈΡ
ΠΠ°ΠΊΠ΅Ρ ΡΠΏΡΠΎΠ΅ΠΊΡΠΈΡΠΎΠ²Π°Π½ Ρ ΡΡΠ΅ΡΠΎΠΌ ΡΠ°ΡΡΠΈΡΡΠ΅ΠΌΠΎΡΡΠΈ ΠΈ Π°Π΄Π°ΠΏΡΠ°ΡΠΈΠΈ ΠΏΠΎΠ΄ ΠΏΡΠΎΠ΅ΠΊΡ.
- ΠΡ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π·Π°ΠΌΠ΅Π½ΠΈΡΡ ΠΌΠΎΠ΄Π΅Π»Ρ Π²Π»Π°Π΄Π΅Π»ΡΡΠ°, ΠΏΠ΅ΡΠ΅Π΄Π°Π²Π°Ρ Π»ΡΠ±ΠΎΠΉ UUID-ΡΠΎΠ²ΠΌΠ΅ΡΡΠΈΠΌΡΠΉ
ownerId
. - ΠΠ°ΠΏΠΊΠΈ Π½Π΅ ΡΠ²Π»ΡΡΡΡΡ ΠΎΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΡΠΌΠΈ β ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΈΠ·Π±ΡΠ°Π½Π½ΠΎΠ΅ ΠΈ Π±Π΅Π· Π½ΠΈΡ .
- ΠΡΡ Π±ΠΈΠ·Π½Π΅Ρ-Π»ΠΎΠ³ΠΈΠΊΠ° ΠΈΠ·ΠΎΠ»ΠΈΡΠΎΠ²Π°Π½Π° Π² ΡΠ΅ΡΠ²ΠΈΡΠ°Ρ
(
FavoriteService
,FavoriteFolderService
) ΠΈ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ Π»Π΅Π³ΠΊΠΎ ΡΠ°ΡΡΠΈΡΠ΅Π½Π° ΠΈΠ»ΠΈ ΠΏΠ΅ΡΠ΅ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π° ΡΠ΅ΡΠ΅Π· DI-ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ. - ΠΠ°Π·Π²Π°Π½ΠΈΡ ΡΠ°Π±Π»ΠΈΡ, ΡΡΠΎΠ»Π±ΡΠΎΠ² ΠΈ ΠΊΠ»ΡΡΠ΅ΠΉ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡ ΠΎΠ±ΡΠΈΠΌ ΡΡΠ°Π½Π΄Π°ΡΡΠ°ΠΌ Laravel ΠΈ ΠΌΠΎΠ³ΡΡ Π±ΡΡΡ ΠΏΠ΅ΡΠ΅ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Ρ ΠΏΡΠΈ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΡΠΈ.
π ΠΡΠΈΠΌΠ΅Ρ: Π·Π°ΠΌΠ΅Π½Π° Π»ΠΎΠ³ΠΈΠΊΠΈ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΡ
Π‘ΠΎΠ·Π΄Π°ΠΉΡΠ΅ ΡΠ²ΠΎΠΉ ΠΊΠ°ΡΡΠΎΠΌΠ½ΡΠΉ ΡΠ΅ΡΠ²ΠΈΡ:
class CustomFavoriteService extends \Alyakin\Favorites\Services\FavoriteService { // ... }
ΠΠ΅ΡΠ΅ΠΎΠΏΡΠ΅Π΄Π΅Π»ΠΈΡΠ΅ Π½ΡΠΆΠ½ΡΠΉ ΠΌΠ΅ΡΠΎΠ΄:
public function addToFavorites(string $ownerId, Model $model, ?string $folderName = null): Favorite { // ΡΠ²ΠΎΡ Π»ΠΎΠ³ΠΈΠΊΠ° β Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, Π»ΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ \Log::info('ΠΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ Π² ΠΈΠ·Π±ΡΠ°Π½Π½ΠΎΠ΅', ['owner_id' => $ownerId]); return parent::addToFavorites($ownerId, $model, $folderName); }
ΠΠ°ΡΠ΅Π³ΠΈΡΡΡΠΈΡΡΠΉΡΠ΅ Π² AppServiceProvider:
$this->app->bind( \Alyakin\Favorites\Services\FavoriteService::class, \App\Services\CustomFavoriteService::class );
Π’Π΅ΠΏΠ΅ΡΡ Laravel Π±ΡΠ΄Π΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π²Π°ΡΡ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ Π²ΠΌΠ΅ΡΡΠΎ Π±Π°Π·ΠΎΠ²ΠΎΠΉ.
π€ Π‘ΠΎΡΡΡΠ΄Π½ΠΈΡΠ΅ΡΡΠ²ΠΎ
ΠΡ ΠΎΡΠΊΡΡΡΡ ΠΊ ΠΏΡΠ΅Π΄Π»ΠΎΠΆΠ΅Π½ΠΈΡΠΌ ΠΈ ΡΠ»ΡΡΡΠ΅Π½ΠΈΡΠΌ!
- Π‘ΠΎΠΎΠ±ΡΠ°ΠΉΡΠ΅ ΠΎΠ± ΠΎΡΠΈΠ±ΠΊΠ°Ρ ΡΠ΅ΡΠ΅Π· Issues
- ΠΡΠΈΡΡΠ»Π°ΠΉΡΠ΅ Pull Requests Ρ ΡΠ»ΡΡΡΠ΅Π½ΠΈΡΠΌΠΈ
- ΠΡΠ΅Π΄Π»Π°Π³Π°ΠΉΡΠ΅ ΠΈΠ΄Π΅ΠΈ ΠΏΠΎ ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΡ ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½ΠΎΡΡΠΈ
π ΠΠΈΡΠ΅Π½Π·ΠΈΡ
This package is open-source and available under the MIT License.