Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Repository Laravel Package

bugover/laravel-repository

Laravel package providing a repository layer to abstract Eloquent data access. Includes base repository classes, common CRUD methods, query helpers, and patterns for cleaner, testable service code in your Laravel apps.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Install the Package:

    composer require bugover/laravel-repository
    

    Publish the configuration:

    php artisan vendor:publish --provider="BUGOVER\Repository\RepositoryServiceProvider" --tag="config"
    
  2. Configure the Package: Update config/repository.php to define:

    • Default cache driver (e.g., redis, file).
    • Cache TTL (default: 60 seconds).
    • Enable/disable caching globally.
  3. Create Your First Repository: Generate a repository class for a model (e.g., User):

    php artisan make:repository UserRepository
    

    (Note: The package doesn’t include a built-in make:repository command, so manually create a class extending BUGOVER\Repository\BaseRepository.)

    Example:

    namespace App\Repositories;
    
    use App\Models\User;
    use BUGOVER\Repository\BaseRepository;
    
    class UserRepository extends BaseRepository
    {
        protected $model = User::class;
        protected $cacheTags = ['users']; // Cache tags for invalidation
    }
    
  4. Bind the Repository in AppServiceProvider:

    public function register()
    {
        $this->app->bind(
            \App\Repositories\UserRepository::class,
            function ($app) {
                return new \App\Repositories\UserRepository();
            }
        );
    }
    
  5. First Usage: Inject the repository into a controller or service:

    use App\Repositories\UserRepository;
    
    class UserController extends Controller
    {
        protected $userRepository;
    
        public function __construct(UserRepository $userRepository)
        {
            $this->userRepository = $userRepository;
        }
    
        public function show($id)
        {
            // Automatically cached with tag 'users'
            return $this->userRepository->find($id);
        }
    }
    
  6. Test Caching:

    • Call find() twice; the second call should return cached data.
    • Update a record via update() or delete(); verify cache invalidation using the users tag:
      php artisan cache:tags
      

Implementation Patterns

Core Workflows

1. CRUD Operations

Replace direct Eloquent calls with repository methods:

// Before
$user = User::find(1);
$user->update(['name' => 'John']);

// After
$user = $this->userRepository->find(1);
$this->userRepository->update($user->id, ['name' => 'John']);

2. Caching Strategies

  • Automatic Caching: Enable for find(), all(), or custom queries by setting $cacheTags in the repository.
  • Manual Cache Control: Use cacheFor() to override TTL or tags:
    $this->userRepository->cacheFor(300)->find($id); // Cache for 5 minutes
    
  • Tag-Based Invalidation: Cache invalidates automatically on create(), update(), or delete() if tags are defined.

3. Query Scopes

Extend the repository to add custom scopes:

namespace App\Repositories;

use BUGOVER\Repository\BaseRepository;

class UserRepository extends BaseRepository
{
    // ...
    public function scopeActive($query)
    {
        return $query->where('active', true);
    }

    public function getActiveUsers()
    {
        return $this->scopeQuery(function ($query) {
            return $this->scopeActive($query);
        });
    }
}

Usage:

$activeUsers = $this->userRepository->getActiveUsers();

4. Relationship Handling

Load relationships with caching:

// Automatically caches posts with tag 'posts'
$this->userRepository->with('posts')->find($id);

5. Bulk Operations

// Create multiple records (cached with 'users' tag)
$this->userRepository->createMany([
    ['name' => 'Alice'],
    ['name' => 'Bob'],
]);

// Delete multiple records (invalidates cache)
$this->userRepository->delete([1, 2, 3]);

Integration Tips

1. Service Layer Pattern

Use repositories in a service layer to decouple business logic:

class UserService
{
    protected $userRepository;

    public function __construct(UserRepository $userRepository)
    {
        $this->userRepository = $userRepository;
    }

    public function registerUser(array $data)
    {
        $user = $this->userRepository->create($data);
        // Trigger cache invalidation for related tags
        Cache::forget(['users', 'user:' . $user->id]);
        return $user;
    }
}

2. API Resource Integration

Cache API responses using repository tags:

use Illuminate\Http\Resources\Json\JsonResource;

class UserResource extends JsonResource
{
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'posts' => PostResource::collection($this->whenLoaded('posts')),
        ];
    }
}

// In controller:
public function index()
{
    return UserResource::collection(
        $this->userRepository->all()
    );
}

3. Event-Driven Cache Invalidation

Listen for model events to invalidate cache:

// In a service provider
public function boot()
{
    User::updated(function ($user) {
        Cache::tags(['users'])->flush();
    });
}

4. Testing Repositories

Mock repositories in tests:

$mockRepository = Mockery::mock(UserRepository::class);
$mockRepository->shouldReceive('find')
    ->once()
    ->with(1)
    ->andReturn(new User());

// Inject into controller/service
$controller = new UserController($mockRepository);

5. Custom Cache Keys

Override default cache keys:

protected function getCacheKey($id = null)
{
    return 'custom_user_' . ($id ?? 'all');
}

Gotchas and Tips

Pitfalls

1. Cache Invalidation Race Conditions

  • Issue: Concurrent update()/delete() calls may miss cache invalidation if not using transactions.
  • Fix: Wrap operations in a transaction:
    DB::transaction(function () use ($user) {
        $this->userRepository->update($user->id, ['name' => 'John']);
    });
    

2. Tag-Based Cache Stampedes

  • Issue: High traffic on find() after cache invalidation can overwhelm the database.
  • Fix: Use cacheFor() with longer TTLs for critical endpoints or implement a cache warming strategy.

3. Laravel 11+ Compatibility

  • Issue: The package may not support Laravel 11+ out of the box (e.g., illuminate/http dependency).
  • Fix: Check composer.json for conflicts and manually patch if needed:
    "require": {
        "laravel/framework": "^11.0",
        "illuminate/http": "^11.0"
    }
    

4. Missing make:repository Command

  • Issue: The package lacks a built-in Artisan command for generating repositories.
  • Fix: Use a custom command or scaffold manually:
    php artisan make:repository UserRepository --model=User
    
    (Create a custom command or use a package like laravel-shift/repositories for scaffolding.)

5. Cache Driver Dependencies

  • Issue: Some cache drivers (e.g., file) may not support tag invalidation reliably.
  • Fix: Use redis or memcached for production:
    'cache' => [
        'driver' => env('CACHE_DRIVER', 'redis'),
    ],
    

6. Event Listener Conflicts

  • Issue: The package registers listeners for creating/updating events, which may conflict with existing listeners.
  • Fix: Disable built-in listeners in config/repository.php:
    'listeners' => [
        'creating' => false,
        'updating' => false,
    ],
    
    Then manually handle cache invalidation in your own listeners.

7. PSR-12 Compliance

  • Issue: The package enforces PSR-12, but your existing code may not comply.
  • Fix: Run php-cs-fixer to standardize your repositories:
    composer require --dev friendsofphp/php-cs-fixer
    vendor/bin/php-cs-fixer fix
    

Debugging Tips

1. Cache Debugging

  • Check cached keys:
    php artisan cache:tags
    
  • Clear cache for testing:
    php artisan cache:clear
    
  • Log cache hits/misses:
    \BUGOVER\Repository\BaseRepository::setDebug(true);
    

2. Query Logging

Enable Eloquent query logging to verify

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
cadot.eu/make
besmartand-pro/php-quality-config
sentix/ai-chatbot
codifyo/ts-generator-bundle
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky