Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improve DatabasePlanRepository documentation #240

Merged
merged 2 commits into from
Apr 22, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 79 additions & 26 deletions docs/12-faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ If required for your billable model, modify the cashier migrations for UUIDs:
```php
// Replace this:
$table->unsignedInteger('owner_id');

// By this:
$table->uuid('owner_id');
$table->uuid('owner_id');
```
And in your `Billable` model add
```php
Expand Down Expand Up @@ -62,19 +62,17 @@ Firstly you create your own implementation of the plan repository and implement
Implement the methods according to your needs and make sure you'll return a `Laravel\Cashier\Plan\Contracts\Plan`.

```php
use App\Plan;
use App\Models\Plan;
use Laravel\Cashier\Exceptions\PlanNotFoundException;
use Laravel\Cashier\Plan\Contracts\Plan as PlanContract;
use Laravel\Cashier\Plan\Contracts\PlanRepository;

class DatabasePlanRepository implements PlanRepository
{
public static function find(string $name)
public static function find(string $name): PlanContract
{
$plan = Plan::where('name', $name)->first();

if (is_null($plan)) {
return null;
}
/** @var Plan $plan */
$plan = Plan::where('name', $name)->firstOrFail();

// Return a \Laravel\Cashier\Plan\Plan by creating one from the database values
return $plan->buildCashierPlan();
Expand All @@ -83,7 +81,7 @@ class DatabasePlanRepository implements PlanRepository
return $plan;
}

public static function findOrFail(string $name)
public static function findOrFail(string $name): PlanContract
{
if (($result = self::find($name)) === null) {
throw new PlanNotFoundException;
Expand All @@ -95,15 +93,20 @@ class DatabasePlanRepository implements PlanRepository
```
::: details Example Plan model (app/Plan.php) with buildCashierPlan and returns a \Laravel\Cashier\Plan\Plan
```php
<?php

namespace App;
namespace App\Models;

use Laravel\Cashier\Plan\Plan as CashierPlan;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Laravel\Cashier\Cashier;
use Laravel\Cashier\Plan\Plan as CashierPlan;
use Money\Currency;
use Money\Money;
use Laravel\Cashier\Order\OrderItemPreprocessorCollection as Preprocessors;

class Plan extends Model
{
use HasFactory;

/**
* Builds a Cashier plan from the current model.
*
Expand All @@ -112,25 +115,64 @@ class Plan extends Model
public function buildCashierPlan(): CashierPlan
{
$plan = new CashierPlan($this->name);
return $plan->setAmount(mollie_array_to_money($this->amount))

return $plan->setAmount($this->getAmount())
->setInterval($this->interval)
->setDescription($this->description)
->setFirstPaymentMethod($this->first_payment_method)
->setFirstPaymentAmount(mollie_array_to_money($this->first_payment_amount))
->setFirstPaymentDescription($this->first_payment_description)
->setFirstPaymentRedirectUrl($this->first_payment_redirect_url)
->setFirstPaymentWebhookUrl($this->first_payment_webhook_url)
->setOrderItemPreprocessors(Preprocessors::fromArray($this->order_item_preprocessors));
->setFirstPaymentMethod(config('cashier.first_payment.method'))
->setFirstPaymentAmount($this->getAmount())
->setFirstPaymentDescription($this->description)
->setFirstPaymentRedirectUrl(route('plans-payment.success', ['plan' => $this->id]))
->setFirstPaymentWebhookUrl(Cashier::firstPaymentWebhookUrl())
->setOrderItemPreprocessors(Preprocessors::fromArray(config('cashier_plans.defaults.order_item_preprocessors')));
}

private function getAmount(): Money
{
return new Money($this->price, new Currency($this->currency));
}
}
```

Note: In this case you'll need to add accessors for all the values (like amount, interval, fist_payment_method etc.)
to make sure you'll use the values from your defaults (config/cashier_plans.php > defaults).
The DB-schema for the above Model could look like the following.

```php
Schema::create('plans', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('description');
$table->string('price');
$table->string('currency');
$table->string('interval');
$table->timestamps();
});
```

You can also create a `PlanFactory`.

```php
class PlanFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
'name' => $this->faker->name,
'description' => $this->faker->sentence,
'price' => '10.00',
'currency' => $this->faker->currencyCode,
'interval' => $this->faker->randomElement(['month', 'year']),
];
}
}
```
:::

Then you just have to bind your implementation to the Laravel/Illuminate container by registering the binding in a service provider
Then you have to bind your implementation to the Laravel/Illuminate container by registering the binding in a service provider

```php
class AppServiceProvider extends ServiceProvider
Expand All @@ -142,5 +184,16 @@ class AppServiceProvider extends ServiceProvider
}
```

In order to test if your implementation is setup correctly, you can run the following code snippet.
```php
use Laravel\Cashier\Plan\Contracts\PlanRepository;
use App\Models\Plan;

Plan::factory()->create(["name" => "test"]);
resolve(PlanRepository::class)->find("test");
```

---

Cashier Mollie will now use your implementation of the PlanRepository. For coupons this is basically the same,
just make sure you implement the CouponRepository contract and bind the contract to your own implementation.
make sure you implement the CouponRepository contract and bind the contract to your own implementation.
Loading