GithubHelp home page GithubHelp logo

Comments (7)

RobertBoes avatar RobertBoes commented on April 28, 2024 3

Hey @Jabirr,

It seems like you'd have to bind the contract Laravel\Cashier\Plan\Contracts\PlanRepository to your own implementation that implements this contract.

You can do this in a service provider of your own like this:

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register the application services.
     */
    public function register()
    {
        $this->app->bind(PlanRepository::class, DatabasePlanRepository::class);
    }
}

Your DatabasePlanRepository class would then contain the logic of fetching the items from the database, but you'll have to make sure you're returning objects that implement Laravel\Cashier\Plan\Contracts\Plan.

You can make your own eloquent Plan model, have it implement Laravel\Cashier\Plan\Contracts\Plan, implement all the required methods, and then a database repository would be something like this:

use App\Plan;
use Laravel\Cashier\Plan\Contracts\PlanRepository;

class DatabasePlanRepository implements PlanRepository
{
    /**
     * @param string $name
     * @return null|\Laravel\Cashier\Plan\Contracts\Plan
     */
    public static function find(string $name)
    {
        return Plan::where('name', $name)->first();
    }

    /**
     * @param string $name
     * @return \Laravel\Cashier\Plan\Contracts\Plan
     */
    public static function findOrFail(string $name)
    {
        return Plan::where('name', $name)->firstOrFail();
    }
}

from cashier-mollie.

Jabirr avatar Jabirr commented on April 28, 2024

Hey @RobertBoes thx for the headstart.
Im trying to figure out what i need to put in a migration to migrate the right data.
I thought of something like this.
image
Do i need to add something in the cashier_plans.php so it can refer to a db too? because when you search for a plan that doesnt exist it will say that the plan doesnt exist. Using your code and then searching for a plan that doesnt exist just gives me a 404 page.
If i do search a plan that exist in my db it will show me this.

image

Idk if im just stupid (which probably is) but i dont really seem to understand what i need to do. If you could help me further that would be great.

-Jabir

from cashier-mollie.

RobertBoes avatar RobertBoes commented on April 28, 2024

I think you're on the right track. If you're using your own implementation of PlanRepository you don't need to worry about the config in cashier_plans (because this isn't used anymore).

The 404 is because, in my example, DatabasePlanRepository->findOrFail() uses the default eloquent method (findOrFail), this throws a ModelNotFound exception. I think you'll need to throw a PlanNotFoundException. By looking at the ConfigPlanRepository, you can just do something like this:

public static function findOrFail(string $name)
{
    if (($result = Plan::where('name', $name)->first()) != null) {
        return $result;
    } else {
        throw new PlanNotFoundException;
    }
}

One thing you're missing, is implementing the Plan contract (Laravel\Cashier\Plan\Contracts\Plan) in your own model:

class Plan extends Model implements Laravel\Cashier\Plan\Contracts\Plan
{

}

If you're using an IDE you should then see you need to implement those methods. You can look how these methods are implemented in Plan. After you've implemented these methods it should work the same the config, but then with your own repository (the DB).

from cashier-mollie.

Jabirr avatar Jabirr commented on April 28, 2024

Hi @RobertBoes

First of all, thx for the quick reply. I kind of figured the implementing out too. I think the only issue is now is that it cant find a currency
image

How ever, searching through the code i found out it finds a plans value like this.
image

If I dd my own plan it will return this.
image

If i dd the plan using the normal plan configuration it will return this.
image

So i guess the next step would be returning the same values as using the normal configuration.
Do you have any idea how i could achieve this?
Thx a lot for helping out too btw!

  • Jabir

from cashier-mollie.

Jabirr avatar Jabirr commented on April 28, 2024

Hey guys,

I figured it out with help of @RobertBoes ofcourse.

First of all to start using an custom PlanRepository. You have to bind the contract Laravel\Cashier\Plan\Contracts\PlanRepository to your own implementation that implements this contract.

You can do this in a service provider of your own like this:

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register the application services.
     */
    public function register()
    {
        $this->app->bind(PlanRepository::class, DatabasePlanRepository::class);
    }
}

Your DatabasePlanRepository class would then contain the logic of fetching the items from the database, but you'll have to make sure you're returning objects that implement Laravel\Cashier\Plan\Contracts\Plan.

You can make your own eloquent Plan model, have it implement Laravel\Cashier\Plan\Contracts\Plan, implement all the required methods, and then a database repository would be something like this:

use App\Plan;
use Laravel\Cashier\Plan\Contracts\PlanRepository;

class DatabasePlanRepository implements PlanRepository
{
    /**
     * @param string $name
     * @return null|\Laravel\Cashier\Plan\Contracts\Plan
     */
    public static function find(string $name)
    {
        return Plan::where('name', $name)->first();
    }

    /**
     * @param string $name
     * @return \Laravel\Cashier\Plan\Contracts\Plan
     */
public static function findOrFail(string $name)
{
    if (($result = Plan::where('name', $name)->first()) != null) {
        return $result;
    } else {
        throw new PlanNotFoundException;
    }
}
}

Now make a model for example Plan.php, I will show mine model. You have to import all the Plan functions into the model and change it with the values you save in your db.


namespace App\Models;


use Illuminate\Database\Eloquent\Model;
use Laravel\Cashier\Order\OrderItemPreprocessorCollection;
use Money\Currency;
use Money\Money;
use Laravel\Cashier\Plan\Contracts\Plan as PlanImplements;


class Plan extends Model implements PlanImplements
{
    protected $fillable = [
        'name', 'amount', 'interval', 'description', 'currency','firstPaymentDescription','firstPaymentAmount'
    ];


    public function getCurrency()
    {
        return $this->attributes['currency'];
    }

    public function getCode()
    {
        return $this->attributes['currency'];


    }

    public function amount()
    {


        $currency = new Currency($this->getCode());
        return new Money($this->attributes['amount'] * 100, $currency);
    }

    /**
     * @param \Money\Money $amount
     * @return \Laravel\Cashier\Plan\Contracts\Plan
     */
    public function setAmount(Money $amount)
    {

    }

    /**
     * @return string
     */
    public function description()
    {
        return $this->attributes['description'];

    }

    /**
     * @return string
     */
    public function interval()
    {
        return $this->attributes['interval'];

    }

    /**
     * @return string
     */
    public function name()
    {
        return $this->attributes['name'];
    }

    /**
     * The amount the customer is charged for a mandate payment.
     *
     * @return \Money\Money
     */
    public function firstPaymentAmount()
    {
        $currency = new Currency($this->getCode());
        return new Money($this->attributes['firstPaymentAmount'] * 100, $currency);
    }

    /**
     * @param \Money\Money $firstPaymentAmount
     * @return Plan
     */
    public function setFirstPaymentAmount(Money $firstPaymentAmount)
    {

    }

    /**
     * @return string
     */
    public function firstPaymentMethod()
    {


    }

    /**
     * @param string $firstPaymentMethod
     * @return Plan
     */
    public function setFirstPaymentMethod(?string $firstPaymentMethod)
    {

    }

    /**
     * The description for the mandate payment order item.
     *
     * @return string
     */
    public function firstPaymentDescription()
    {

        return $this->attributes['firstPaymentDescription'];
    }

    /**
     * @param string $firstPaymentDescription
     * @return Plan
     */
    public function setFirstPaymentDescription(string $firstPaymentDescription)
    {

    }

    /**
     * @return string
     */
    public function firstPaymentRedirectUrl()
    {
        return "http://localhost:8000/redirect";
    }

    /**
     * @param string $redirectUrl
     * @return Plan
     */
    public function setFirstPaymentRedirectUrl(string $redirectUrl)
    {

    }

    /**
     * @return string
     */
    public function firstPaymentWebhookUrl()
    {
        return "webhookurl";

    }

    /**
     * @param string $webhookUrl
     * @return Plan
     */
    public function setFirstPaymentWebhookUrl(string $webhookUrl)
    {
    }

    /**
     * @return \Laravel\Cashier\Order\OrderItemPreprocessorCollection
     */
    public function orderItemPreprocessors()
    {

    }

    /**
     * @param \Laravel\Cashier\Order\OrderItemPreprocessorCollection $preprocessors
     * @return \Laravel\Cashier\Plan\Contracts\Plan
     */
    public function setOrderItemPreprocessors(OrderItemPreprocessorCollection $preprocessors)
    {


        $this->orderItemPreprocessors = $preprocessors;

        return $this;
    }
}

Now you can insert your plans into a db.
image

This was a quick fix but I am 100% sure that this can be made better.
I also want to thanks @RobertBoes for his time and help.
If someone has a beter way of achieving this. Id like to know that too!

from cashier-mollie.

alexander-rieder avatar alexander-rieder commented on April 28, 2024

@Jabirr could you also post your migration file? :)

from cashier-mollie.

Jabirr avatar Jabirr commented on April 28, 2024

@alexander-rieder ofc,

public function up()
{
Schema::create('plans', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->text('description')->nullable();
$table->string('interval')->default('monthly');
$table->double('amount');
$table->string('currency')->default('EUR');
$table->text('firstPaymentDescription')->nullable();
$table->double('firstPaymentAmount')->default(0.01);
$table->string('firstPaymentCurrency')->default('EUR');
$table->text('modules');
$table->softDeletes();
$table->timestamps();
});
}

The modules field is something i used my self to assign certain modules to plans.

from cashier-mollie.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.