Create reusable database queries and data objects in Laravel.
- PHP >= 8.1
- Laravel >= 9.0
Install the package via Composer:
composer require mayankjanidev/laravel-storeOften, we have business critical data that we want to manage in a project. We might use them in controllers, services, console commands, admins, and other pieces of code. Laravel Store helps you centralize this critical data, so it's easy to manage and update it from time to time. This helps debug things faster and avoids query duplication scattered around the codebase.
Create a store via the command line:
php artisan make:store TopRatedMoviesA store file will be created in App\Stores\TopRatedMovies.
You can also specify your own location, like for example in App\Data:
php artisan make:store TopRatedMovies --namespace=DataStore example:
namespace App\Stores;
use Illuminate\Database\Eloquent\Builder;
use Mayank\Store\QueryStore;
use App\Models\Movie;
class TopRatedMovies extends QueryStore
{
public function query(): Builder
{
return Movie::orderByDesc('rating');
}
}You can now use this class anywhere in your codebase to fetch data. For example, in a controller:
class TopRatedMoviesController extends Controller
{
public function index(TopRatedMovies $topRatedMovies)
{
$movies = $topRatedMovies->get();
...
}
}This example uses dependency injection, but you can also manually instantiate the classes.
$movies = (new TopRatedMovies)->get();Congrats! Now you have one central place where you can customize the database queries, and you won't have to hunt down controllers to find it. But this is just the beginning, Laravel Store offers even more powerful features to manage data in your application.
Every store has its own methods to manage cache.
Get cached data:
(new TopRatedMovies)->getCachedData();Build cache:
(new TopRatedMovies)->cache();Clear cache:
(new TopRatedMovies)->clearCache();By default, cache duration is forever, and the cache key is calculated by the class name ('top-rated-movies' in this case). But you can customize it.
class TopRatedMovies extends QueryStore
{
public function cacheKey(): string
{
return 'best-movies';
}
public function cacheDuration(): DateTime
{
return now()->addHours(2);
}
}By default, all the data specified in the query() method will be cached by executing ->get() on the query. But you can cache a portion of the data.
class TopRatedMovies extends QueryStore
{
public function cacheData(): Collection
{
return $this->query()->limit(250)->get();
}
}You can get the paginated data for your database queries.
(new TopRatedMovies)->paginate();
(new TopRatedMovies)->simplePaginate();This just calls the ->paginate() method on the query(), so it works the same as Laravel Pagination.
You might have some data in your application that is in a different format, like an array, and does not return a database query. In those cases, you can use a CustomStore where you can return data in your own format rather than being dependent on Laravel model and query builder.
use Mayank\Store\CustomStore;
class Languages extends CustomStore
{
public function data(): array
{
return ['English', 'Spanish', 'French'];
}
}Create a custom store via the command line:
php artisan make:store Languages --customAll the caching methods work exactly the same as in QueryStore.
If you manage your data via the command line or via Task Scheduling, Laravel Store provides cache specific commands:
Cache data:
php artisan store:cache TopRatedMoviesClear cache:
php artisan store:clear TopRatedMoviesUse in Task Scheduling:
Schedule::command('store:cache TopRatedMovies')->daily();You might want to invalidate the cache or rebuild it when the underlying data is changed. Combine this package with Laravel Observers to achieve the same.
class MovieObserver
{
public function updated(Movie $movie): void
{
(new TopRatedMovies)->clearCache();
}
}In some cases, you might want to show different variations of the same data. For example, in your API you would like to show a very small subset of data. As Laravel Store is just a class, you can add your own methods to it.
class TopRatedMovies extends QueryStore
{
public function query(): Builder
{
return Movie::orderByDesc('rating');
}
public function getDataForApi(): Collection
{
return $this->query()->limit(10)->get();
}
}In some cases, your data could be dependent on some other piece of data. In those cases, you could simply use constructors to inject it.
class TopRatedMovies extends QueryStore
{
public function __construct(protected Country $country)
{
}
public function query(): Builder
{
return Movie::orderByDesc('rating')->where('country', $this->country->name);
}
}Laravel's Service Container can automatically resolve your dependencies.
This package is released under the MIT License.