PHP code example of ebects / laravel-cache-group

1. Go to this page and download the library: Download ebects/laravel-cache-group library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

ebects / laravel-cache-group example snippets




namespace App\Cache\Groups;

use App\Actions\Posts\CreatePost;
use App\Actions\Posts\UpdatePost;
use App\Actions\Posts\FetchPosts;
use Ebects\LaravelCacheGroup\Contracts\CacheGroupInterface;

class PostsCacheGroup implements CacheGroupInterface
{
    public static function getPrefix(): string
    {
        return 'posts.list';
    }

    public static function getConfig(): array
    {
        return [
            'scope' => 'user',         // 'global', 'user', 'role', or any custom scope
            'ttl' => 3600,             // 1 hour
            'also_invalidate' => [     // cascade invalidation
                'dashboard.stats',
            ],
        ];
    }

    public static function getClasses(): array
    {
        return [FetchPosts::class];    // classes that READ this cache
    }

    public static function getRemoveClasses(): array
    {
        return [
            CreatePost::class,                           // simple: invalidates this group
            UpdatePost::class => ['posts.detail'],       // also invalidates posts.detail
        ];
    }
}

use Ebects\LaravelCacheGroup\CacheRegistry;
use App\Cache\Groups\PostsCacheGroup;
use App\Cache\Groups\DashboardCacheGroup;

public function boot(): void
{
    CacheRegistry::registerMany([
        PostsCacheGroup::class,
        DashboardCacheGroup::class,
    ]);
}

use Ebects\LaravelCacheGroup\CacheGroupStore;

// In controller — auto-resolves user/role from auth
$posts = CacheGroupStore::remember(
    'posts.list',                            // prefix
    'list',                                  // variant
    fn() => Post::paginate(20),              // callback
    extraParams: request()->all()            // unique per filter/page
);

// Resource/detail cache — scope-aware!
$post = CacheGroupStore::rememberResource(
    'posts.list',                            // prefix
    'detail',                                // variable name
    $postId,                                 // resource ID
    fn() => Post::findOrFail($postId)        // callback
);

use Ebects\LaravelCacheGroup\Traits\InvalidatesCache;

class CreatePost
{
    use InvalidatesCache;

    public function handle(array $data): Post
    {
        $post = Post::create($data);

        // Auto-detect which caches to invalidate from class mapping
        $this->invalidateCache();

        return $post;
    }
}



namespace App\Cache;

use Ebects\LaravelCacheGroup\Contracts\ScopeResolver;

class AppScopeResolver implements ScopeResolver
{
    public function resolve(string $scope): ?string
    {
        $user = auth()->user();
        if (!$user) return null;

        return match($scope) {
            'user' => (string) $user->id,
            'role' => $user->role->slug,
            'tenant' => (string) $user->tenant_id,
            default => null,
        };
    }

    public function resolveFor(string $scope, mixed $target): ?string
    {
        if (is_string($target)) return $target;

        return match($scope) {
            'user' => (string) $target->id,
            'role' => is_string($target) ? $target : $target->role->slug,
            'tenant' => (string) $target->tenant_id,
            default => null,
        };
    }

    public function hasActiveSession(): bool
    {
        return auth()->check();
    }
}

// config/cache-group.php
'scope_resolver' => App\Cache\AppScopeResolver::class,

// Simple
$data = CacheGroupStore::remember('dashboard.stats', 'summary', fn() => expensive());

// With request params for unique key per page/filter
$data = CacheGroupStore::remember('posts.list', 'list', fn() => Post::paginate(), extraParams: request()->all());

// Custom TTL
$data = CacheGroupStore::remember('reports', 'monthly', fn() => generateReport(), ttl: 7200);

// In queue job — no auth session available
$data = CacheGroupStore::rememberFor(
    'dashboard.stats', 'summary',
    'user', $userId,                    // explicit scope + target
    fn() => expensiveCalculation()
);

// Auto-resolve scope from auth
$detail = CacheGroupStore::rememberResource(
    'surat_masuk.main',                 // prefix
    'detail',                           // variable name
    $suratId,                           // resource ID
    fn() => Surat::findOrFail($suratId)
);

// Explicit scope for queue
$detail = CacheGroupStore::rememberResourceFor(
    'surat_masuk.main', 'detail', $suratId,
    'user', $userId,
    fn() => Surat::findOrFail($suratId)
);

// Check if cache exists
CacheGroupStore::has('posts.list', 'list');

// Forget specific entry
CacheGroupStore::forget('posts.list', 'list');

use Ebects\LaravelCacheGroup\Traits\InvalidatesCache;

class UpdatePost
{
    use InvalidatesCache;

    public function handle(Post $post, array $data): Post
    {
        $post->update($data);

        // Auto from class mapping (HTTP context)
        $this->invalidateCache();

        // Explicit scope + target (queue safe)
        $this->invalidateCacheFor('user', $userId);

        // Specific prefix
        $this->invalidateCacheByPrefix('posts.list');

        // Nuclear — all users
        $this->invalidateAllCache('posts.list');

        // Multiple targets
        $this->invalidateCacheForMany('user', [$userId1, $userId2]);

        return $post;
    }
}

use Ebects\LaravelCacheGroup\Facades\CacheGroup;

CacheGroup::invalidate('posts.list');
CacheGroup::invalidateFor('posts.list', 'user', $userId);
CacheGroup::invalidateAll('master.data');
CacheGroup::forceInvalidate('dashboard.stats');

$result = $this->forceInvalidateCache('dashboard.stats');

if ($result['throttled']) {
    return response()->json([
        'message' => "Please wait {$result['retry_after']} seconds",
    ], 429);
}

// config/cache-group.php
'redis_cluster_mode' => true,  // force cluster
'redis_cluster_mode' => false, // force tags
'redis_cluster_mode' => null,  // auto-detect (default)

use Ebects\LaravelCacheGroup\CacheManager;
use Ebects\LaravelCacheGroup\Testing\FakeCacheManager;

public function test_creating_post_invalidates_cache()
{
    $fake = new FakeCacheManager();
    $this->app->instance(CacheManager::class, $fake);

    $action = new CreatePost();
    $action->handle(['title' => 'Test']);

    $fake->assertInvalidated('posts.list');
    $fake->assertNotInvalidated('unrelated.prefix');
    $fake->assertInvalidationCount(2);
}