PHP code example of studocu / cacheable-entities

1. Go to this page and download the library: Download studocu/cacheable-entities 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/ */

    

studocu / cacheable-entities example snippets


class RecommendedBooksQuery implements Cacheable, SerializableCacheable
{
    public function getCacheTTL(): int
    {
        return 3600 * 24;
    }

    public function getCacheKey(): string
    {
        return "books:popular.v1";
    }

    public function get(): Collection
    {
        return Book::query()
            ->wherePopular()
            ->orderByDesc('document_popularity_scores.score')
            ->take(config('popular.books.limit'))
            ->get();
    }
    
    public function serialize(mixed $value): array
    {
        return $value->pluck('id')->all();
    }
    
    public function unserialize(mixed $value): Collection
    {
        return Book::query()->findMany($value);
    }
}

$query = new RecommendedBooksQuery();

// Get a non-blocking cache result in the web endpoint.
resolve(AsyncCache::class)->get($query);

// Get a blocking cache result in the API endpoint.
resolve(SyncCache::class)->get($query);

// Get real time value
$query->get();



use Author;
use Book;
use Illuminate\Database\Eloquent\Collection;
use StuDocu\CacheableEntities\Contracts\Cacheable;
use StuDocu\CacheableEntities\Contracts\SerializableCacheable;

class AuthorPopularBooksQuery implements Cacheable
{
    public const DEFAULT_LIMIT = 8;

    public function __construct(
        protected readonly Author $author,
        protected readonly int $limit = self::DEFAULT_LIMIT,
    ) {
    }

    public function getCacheTTL(): int
    {
        return 3600 * 24;
    }

    public function getCacheKey(): string
    {
        return "authors:{$this->author->id}:books:popular.v1";
    }

    public function get(): Collection
    {
        return Book::query()
            ->join('book_popularity_scores', 'book_popularity_scores.book_id', '=', 'books.id')
            ->where('author_id', $this->author->id)
            ->whereValid()
            ->whereHas('ratings')
            ->orderByDesc('document_popularity_scores.score')
            ->take($this->limit)
            ->get()
            ->each
            ->setRelation('author', $this->author);
    }
}

// Usage

// ...

$query = new AuthorPopularBooksQuery($author);

// Get a non-blocking cache result in the web endpoint.
resolve(AsyncCache::class)->get($query);

// Get a blocking cache result in the API endpoint.
resolve(SyncCache::class)->get($query);



// [...]
use StuDocu\CacheableEntities\Contracts\SerializableCacheable;

class AuthorPopularBooksQuery implements Cacheable, SerializableCacheable
{
   // [...]
   
   /**
    * @param Collection<Book> $value
    * @return array<int>
    */
   public function serialize(mixed $value): array
   {
       // `$value` represents the computed value of this query; it will be what we will get when calling self::get().
       return $value->pluck('id')->all();
   }
   
    /**
     * @param  int[]  $value
     * @return  Collection<int, Book>
     */
    public function unserialize(mixed $value): Collection
    {
        // `$value` represents what we've already cached previously, it will the result of self self::serialize(...)
        
        $booksFastAccess = array_flip($value);
        
        $books = Book::query()
            ->findMany($value)
            ->sortBy(fn (Book $book) => $booksFastAccess[$book->id] ?? 999)
            ->values();
    
        $this->setRelations($books);
    
        return $books;
    }
    
    /**
     * @param  ReturnStructure  $books
     */
    private function setRelations(Collection $books): void
    {
        $books->each->setRelation('author', $this->author);

        // Generally speaking, you can do eager loading and such in a similar fashion (for ::get and ::unserialize).
    }
}

// Usage is still unchanged.
$query = new AuthorPopularBooksQuery($author);

// Get a non-blocking cache result in the web endpoint.
resolve(\StuDocu\CacheableEntities\AsyncCache::class)->get($query);

// Get a blocking cache result in the API endpoint.
resolve(\StuDocu\CacheableEntities\SyncCache::class)->get($query);

    /**
     * @return ReturnStructure
     *
     * @throws CorruptSerializedCacheValueException
     */
    public function unserialize(mixed $value, mixed $default = null): Collection
    {
        // Corrupt format cached
        if (! is_array($value)) {
            throw new CorruptSerializedCacheValueException();
        }

        if (empty($value)) {
            return Collection::empty();
        }

        $books = Book::query()->findMany($value);

        $this->eagerLoadRelations($books);

        return $books;
    }

// Retaining the original order with array_search
$books = Book::query()
    ->findMany($value)
    ->sortBy(fn (Book $book) => array_search($book->id, $value))
    ->values();

// Retaining the original order with array_flip.
// A faster alternative than the above, using direct array access instead of `array_search`.`
$booksFastAccess = array_flip($value);
$book = Book::query()
    ->findMany($value)
    ->get()
    ->sortBy(fn (Book $book) => $booksFastAccess[$book->id] ?? 999)
    ->values();

// Retaining the original order with SQL.
$books = Book::query()
    ->orderByRaw(DB::raw('FIELD(id, ' . implode(',', $value) . ')'))
    ->get();


$query = new AuthorPopularBooks($author);
// Invalidate the cache (for example, in an event listener).
resolve(\StuDocu\CacheableEntities\SyncCache::class)->forget($query);



use Illuminate\Database\Eloquent\Collection;
use StuDocu\CacheableEntities\Contracts\SupportsDefaultValue;

class AuthorPopularBooks implements Cacheable, SupportsDefaultValue
{
   public function getCacheMissValue(): Collection
   {
      return Collection::empty();
   }
}


// [...]
use StuDocu\CacheableEntities\Concerns\SelfCacheable;

class AuthorPopularBooksQuery implements Cacheable, SerializableCacheable
{
   use SelfCacheable;
   
   // [...]
}

$query = new AuthorPopularBooksQuery($author);

// Get a non-blocking cache result in the web endpoint.
$query->getCachedAsync();

// Get a blocking cache result in the API endpoint.
$query->getCached();

// Forget the cached value.
$query->forgetCache();

/**
 * @phpstan-type ReturnStructure Collection<User>
 * @implements Cacheable<ReturnStructure>
 * @implements SerializableCacheable<ReturnStructure, string>
 * @implements SupportsDefaultValue<ReturnStructure>
 */
class CourseQuery implements Cacheable, SerializableCacheable, SupportsDefaultValue
{
    /** @phpstan-use SelfCacheable<ReturnStructure> */
    use SelfCacheable;
}