【问题标题】:Laravel Spark extend Laravel\Cashier vendor class to override functionLaravel Spark 扩展 Laravel\Cashier 供应商类以覆盖功能
【发布时间】:2019-11-09 16:28:18
【问题描述】:

我希望覆盖 Cashier 的 SubscriptionBuilder::buildPayload()。看起来像:

    protected function buildPayload()
    {
        return array_filter([
            'billing_cycle_anchor' => $this->billingCycleAnchor,
            'coupon' => $this->coupon,
            'expand' => ['latest_invoice.payment_intent'],
            'metadata' => $this->metadata,
            'plan' => $this->plan,
            'quantity' => $this->quantity,
            'tax_percent' => $this->getTaxPercentageForPayload(),
            'trial_end' => $this->getTrialEndForPayload(),
            'off_session' => true,
        ]);
    }

我希望为此添加 1 个参数,即 'collection_method': 'invoice'

所以我试图覆盖这个函数,以便我可以修改它。

我尝试了一些事情,即遵循以下一些答案:

Strategy to override a class in a library installed with Composer

Laravel 5.7 Override vendor class and extend old one

我已在App\SparkOverrides\ 中添加了我的CustomSubscriptionBuilder

<?php

namespace Laravel\Cashier;

class CustomSubscriptionBuilder extends SubscriptionBuilder
{
    protected function buildPayload()
    {
        dd('here');
    }
}

然后在composer.json我加了:

"autoload": {
        ...
        "files": [
            "app/SparkOverrides/CustomSubscriptionBuilder.php"
        ]
    },

然后我运行composer dump-autoload。但是当我尝试创建订阅时,dd() 永远不会受到打击。为了让事情变得更混乱,我在vendor buildPayload() 添加了一个转储和死机,而且也没有受到影响。

我觉得我很接近,但我错过了一些东西。感谢您的帮助。

【问题讨论】:

  • 仅仅因为你创建了一个扩展另一个类的类并不意味着任何人都知道你的新类存在......在需要这个 SubscriptionBuilder 的地方,它被硬编码到Billable trait @newSubscription
  • 这是有道理的,但它并没有让我更接近于弄清楚如何解决这个问题。
  • 它是硬编码在特征中的,所以扩展特征并覆盖方法并在模型中使用新的扩展特征或在模型中覆盖方法
  • 感谢@lagbox 的提示!我能够得到它。
  • 很好,很高兴你得到它:)

标签: php laravel laravel-cashier laravel-spark


【解决方案1】:

想通了!感谢@lagbox 为我指明了正确的方向。

我创建了一个CustomBillable 类和一个CustomSubscriptionBuilder 类。

这两个类都在app/SparkOverrides/

<?php

namespace App\SparkOverrides;

use Laravel\Spark\Billable;

trait CustomBillable
{
    use Billable;

    /**
     * Overriding Cashier's newSubscription to use
     * my CustomSubscriptionBuilder
     */
    public function newSubscription($subscription, $plan)
    {
        return new CustomSubscriptionBuilder($this, $subscription, $plan);
    }
}
<?php

namespace App\SparkOverrides;

use Laravel\Cashier\SubscriptionBuilder;

class CustomSubscriptionBuilder extends SubscriptionBuilder
{
    protected function buildPayload()
    {
        return array_filter([
            'billing_cycle_anchor' => $this->billingCycleAnchor,
            'coupon' => $this->coupon,
            'expand' => ['latest_invoice.payment_intent'],
            'metadata' => $this->metadata,
            'plan' => $this->plan,
            'quantity' => $this->quantity,
            'tax_percent' => $this->getTaxPercentageForPayload(),
            'trial_end' => $this->getTrialEndForPayload(),
            'off_session' => true,
            'collection_method' => 'send_invoice',
            'days_until_due' => 30,
        ]);
    }
}

然后我用 Spark\User 上的 CustomBillable 特征替换了 Billable 特征。

<?php

namespace Laravel\Spark;

use App\SparkOverrides\CustomBillable;
use Illuminate\Support\Str;
use Illuminate\Notifications\RoutesNotifications;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use CustomBillable, HasApiTokens, RoutesNotifications;
    ...
}

应用程序的User 扩展了Spark\User。所以现在当newSubscription() 被调用时,它使用CustomBillablenewSubscription(),而newSubscription() 又使用CustomSubscriptionBuilder

我希望这可以帮助某人。已经在这个上修修补补了一段时间。

【讨论】:

  • 正确的做法是写一个实现Laravel\Spark\Contracts\Interactions\Subscribe接口的类,通过SparkServiceProvider类的register方法注入到容器中。看看Laravel\Spark\Providers\SparkServiceProvider::registerServices()
【解决方案2】:

我迟到了,但你可以重写从 Laravel\Spark\User 类继承的 App\User 类中的 newSubscription 方法。只是一个想法......

【讨论】:

    猜你喜欢
    • 2019-02-20
    • 2019-04-05
    • 2019-02-18
    • 2018-06-04
    • 2018-04-08
    • 1970-01-01
    • 2018-03-29
    • 2017-05-05
    • 2021-06-07
    相关资源
    最近更新 更多