L4.2 Расширить/переопределить кассу, чтобы добавить налоговую функцию

Я использую Laravel 4.2 с Cashier, и мне нужно изменить его защищенную функцию buildPayload(), но я не хочу делать это непосредственно в файле поставщика, так как я могу сломать код при обновлении компоновщика... Как мне перейти к переопределить эту функцию моей собственной логикой?

В настоящее время я использую Cashier в одном из своих контроллеров, выполняя:

$user->subscription('testplan')
                    ->create(Input::get('stripeToken'), [
                        'email' => '[email protected],
                    ]);

Но я хочу добавить параметры withTax()... Вот так:

$user->subscription('testplan')
                        ->withTax(10)
                        ->create(Input::get('stripeToken'), [
                            'email' => '[email protected],
                        ]);

Я уже знаю, как это сделать прямо в файле StripeGateway.php, но это плохая практика...

Я знаю, что мне нужно добавить:

protected $taxPercent = 0;

    public function withTax($tax)
    {
        $this->taxPercent = $tax;

        return $this;
    }

    protected function buildPayload()
    {
        $payload = [
            'plan' => $this->plan, 'prorate' => $this->prorate,
            'quantity' => $this->quantity, 'trial_end' => $this->getTrialEndForUpdate(),
            'tax_percent' => $this->taxPercent,
        ];

        return $payload;
    }

Чего я не знаю, так это того, как добавить этот код не непосредственно в исходный файл Cashier.


person raphjutras    schedule 30.08.2015    source источник


Ответы (2)


Мне удалось найти, как это сделать самостоятельно, я впервые делаю такие вещи... Пожалуйста, поправьте меня, если мой метод неверен!

Первый:

Я создал папку с именем Lib\Cashier, например: laravel/app/Lib/Cashier.

Затем я создал 2 файла: BillableTrait.php и NewStripeGateway.php.

Код BillableTrait.php:

<?php namespace Lib\Cashier;

use Laravel\Cashier;
use Lib\Cashier\NewStripeGateway as StripeGateway;

trait BillableTrait {
    use Cashier\BillableTrait;

    /**
     * Get a new billing gateway instance for the given plan.
     *
     * @param  \Laravel\Cashier\PlanInterface|string|null  $plan
     * @return \Laravel\Cashier\StripeGateway
     */
    public function subscription($plan = null)
    {
        if ($plan instanceof PlanInterface) $plan = $plan->getStripeId();

        return new StripeGateway($this, $plan);
    }


}

Для NewStripeGateway.php:

<?php namespace Lib\Cashier;

use Laravel\Cashier\StripeGateway;

class NewStripeGateway extends StripeGateway {

    protected $taxPercent = 0;

    public function withTax($tax)
    {
        $this->taxPercent = $tax;

        return $this;
    }

    protected function buildPayload()
    {
        $payload = [
            'plan' => $this->plan, 'prorate' => $this->prorate,
            'quantity' => $this->quantity, 'trial_end' => $this->getTrialEndForUpdate(),
            'tax_percent' => $this->taxPercent,
        ];

        return $payload;
    }
}

А затем я отредактировал свою модель, использующую Cashier, вот так (изменил только блок USE):

use Lib\Cashier\BillableTrait;
use Laravel\Cashier\BillableInterface;

Теперь я могу сделать это напрямую, чтобы установить налог на подписку:

$user->subscription('testplan')
                        ->withTax(10)
                        ->create(Input::get('stripeToken'), [
                            'email' => '[email protected]',
                        ]);

Он работает отлично!! Если я что-то сделал не так, пожалуйста, обратите внимание на изменения, я впервые копаюсь в классах PHP (черты, расширения и т. д.) самостоятельно.

Благодарю вас!

Рафаэль

person raphjutras    schedule 30.08.2015
comment
Да, единственное, что я бы изменил, это не пытаться сделать его похожим на оригинал (use Lib\Cashier\NewStripeGateway as StripeGateway;). Я бы оставил его как «NewStripeGateway», а затем вместо new StripeGateway вы бы сделали new NewStripeGateway. также вы можете переопределить метод subscription в своей пользовательской модели [в случае, если вы используете черту Billable только один раз], но то, что вы сделали, вероятно, более организовано. [просто хотел упомянуть, что это не единственный способ переопределить трейт] - person Gal; 31.08.2015

Вы можете добавить метод getTaxPercent в свою модель user, и он также будет рассчитывать налоги.документы Laravel< /а>

к сожалению, нет возможности расширить класс StripeGateway, поскольку он жестко запрограммирован в черте Billable, что вы можете сделать, так это изменить эти функции -

public function charge($amount, array $options = []) { return (new StripeGateway($this))->charge($amount, $options); } public function subscription($plan = null) { return new StripeGateway($this, $plan); } в вашем классе user, проблема здесь в том, что вы никогда не можете знать, что изменится в Billable, они могут изменить имена функций и добавить еще несколько, которые используют StripeGateway, и вы не узнаете, пока не появятся ошибки.

Первый вариант, вероятно, был бы намного лучше, так как вам не нужно будет каждый раз упоминать метод withTax.

person Gal    schedule 30.08.2015
comment
Вы знаете, будет ли это работать даже с Cashier v2.0.7, совместимым с Laravel 4.2? Документы, касающиеся налогов, предназначены для Laravel 5/Cashier v5. - person raphjutras; 30.08.2015
comment
похоже, что никто не собирается обновлять Laravel/cashier 2.0 и из исходников похоже, он не поддерживает этот метод. Я не вижу никаких причин, почему бы не обновиться до 5.1, да, это непростая задача, но это единственный способ оставаться в курсе событий, здесь есть несколько приятных новых функций, а также он намного более организован, чем 4.X. если это не вариант, поэтому я бы выбрал метод, переопределяющий и расширяющий класс StripeGateway, и добавляю ваш метод withTax - person Gal; 30.08.2015
comment
Я сделаю переопределяющий/расширяющий «вариант», так как переход на 5.1 на самом деле не вариант для меня в данный момент... Я просто заблокирую обновление до версии 2.0.7 в моем composer.json, чтобы быть уверенным, что никакие изменения не будут добавлены в будущем... Но мой первоначальный вопрос заключается именно в том, как это сделать. Я знаю, что должен расширить/переопределить, но я не знаю, как это сделать, я недостаточно хорошо разбираюсь в PHP, чтобы точно знать, что делать, Не могли бы вы дать мне простые сведения о том, как это сделать, и я отмечу ваш точный ответ как правильный;) Спасибо, Гал. - person raphjutras; 31.08.2015