Reputation: 3855
I'm learning Stripe API through Cashier with a small Laravel app. My goal is to store subscription plans in a local data source other than a DB. Ideally, I would like to end up with a Collection
of static (i.e. permanent) data, possibly in the form of Plan
objects. Each plan would contain name
, description
, and price
which will hardly ever be modified, so the data could simply be hardcoded in PHP. I envision to treat this data just like any Eloquent model:
class MembershipController extends Controller
{
public function index() // dependency injection here? hmm..
{
return view('membership')->with('plans', Plan::all());
}
Here are my considerations for the data source / structure so far:
Plan
model and persist the three plans in a plans
table. However, because my plans will rarely ever change, I would have to fetch the same data from the DB over and over again on each HTTP request. Even worse, if I do happen to change my plans in the future, I would need to update them at two places -- Stripe dashboard and local database, which is cumbersome and counter-intuitive. What if I or any other person simply forget to? I feel that there needs to be a single data source.Plan
Model. In this case, I would have to fetch Plan
s using Stripe API. Again, this operation would be (even more) expensive, since every time a request is made to the server, a syncronous request will be made to Stripe to fetch the plans, and the app will be idle untill the API responds back with the data. This, to me, is very slow and inefficient.Can you suggest any other design patterns or data structures that will be useful in this case? If Service Provider would be the best-recommended approach, can you give a simple example of how to use it? I read the docs and although the given example was vague, I ended up with the following:
class PlanProvider extends ServiceProvider
{
protected $defer = true;
public function boot() { }
public function register()
{
$this->app->singleton(Collection::class, function ($app) {
return new Collection([ // that's probably not right...
'basic' => [
new Plan([
'name' => 'basic',
'description' => 'Basic Plan',
'price' => 999
])
]
]);
});
}
public function provides()
{
return [Collection::class];
}
}
I feel it's not right. And how would I inject this collection into a controller anyways?
Thanks
Upvotes: 4
Views: 2832
Reputation: 1124
I found this one the other day... Might help with what you're looking for: https://github.com/WebLogin/laravel-lookup
Allows you to create static Elaquent compatible models.
And there's also this one: https://github.com/squirephp/squire#creating-your-own-models
Upvotes: 0
Reputation: 21681
From the stack answer, you can use view()->share()
to share data across all controller globally.
Just follows the given three steps and done.
UPDATE
You can also use Repository
approach to use global data at other controller. This is something like below:
Create PlanRepository.php
under app/Http/Repository/
:
<?php
namespace App\Http\Repository;
/**
* Plan Repository class
*/
class PlanRepository
{
/**
* Get a list of all plans
*
* @return array Array containing list of all plans
*/
public function getPlanData()
{
return [
'name' => 'basic',
'description' => 'Basic Plan',
'price' => 999
];
}
}
And use into respective controller by injecting above repository like:
public $planList;
public function __construct(PlanRepository $plan)
{
$this->planList = $plan->getPlanData();
}
Even you can pass these data to view like:
public function index(PlanRepository $plan)
{
$planList = $plan->getPlanData();
return view('welcome', compact('planList'));
}
Upvotes: 1