XF 2.2 class Purchase implements \ArrayAccess -> could I extend it?

Scandal

Active member
Hello guys!
I want to extend this class:
XF\Purchasable\Purchase
(class Purchase implements \ArrayAccess)

Is that possible?
I didn't achieved it via XFCP system.

Basically I want to inject some code via an addon to change the cost (not the currency) for any purchasable item instead of extend each custom (non-xF2 default like User Upgrades) purchasable item class. Maybe on both displayable and purchaserequest cost.
 

NikitOS

Well-known member
You can extend the XF\Repository\Purchase class and change the cost in the insertPurchaseRequest function.

PHP:
    public function insertPurchaseRequest(XF\Purchasable\Purchase $purchase)
    {
        $purchase->cost = 123;

        return parent::insertPurchaseRequest($purchase);
    }
 

Scandal

Active member
You can extend the XF\Repository\Purchase class and change the cost in the insertPurchaseRequest function.

PHP:
    public function insertPurchaseRequest(XF\Purchasable\Purchase $purchase)
    {
        $purchase->cost = 123;

        return parent::insertPurchaseRequest($purchase);
    }
Thanks for this NikitOS! Very nice suggestion. (y)

But what as far as it concerns the displayable price (cost) on the pages, before click the payment button (which triggers the purchaserequest insert) ?

Example: the User Upgrade entity has the cost_amount column which used in addition to the getCostPhrase() method.
ok, I could extend the UserUpgrade entity, convert the cost_amount column to a getter and change the price there too, so on the /account/upgrades/ page to see the modified cost before click on the pay button.
But I need a solution which would change the cost or/and getCostPhrase() for any purchasable item instead of extend each purchasable (UserUpgrade etc) item class.

Any idea? :)
 

NikitOS

Well-known member
In addition to the above extension, you need to extend XF\Data\Currency::languageFormat and change the value variable.
 

Scandal

Active member
In addition to the above extension, you need to extend XF\Data\Currency::languageFormat and change the value variable.
That's a nice solution for static cost values. What if I need access on the PaymentProfile entity to fetch some values which will calculate the new price?

Of course on the insertPurchaseRequest() method/ extension you suggested, there is access via $purchase->paymentProfile. So all fine with the purchaserequest part, I can calculate the new cost.

Inside XF\Data\Currency::languageFormat I have no access to something, just to apply a static value.

It could be very useful if I could have access to change the cost value in a more open environment, no so closed on languageFormat method. Do I miss something? :)
 

Scandal

Active member
Is that possible to extend class Purchase implements \ArrayAccess? (XF\Purchasable\Purchase) ?
It would be more normalize if I could modify the protected $cost; via the public function __get($key) (for $key == 'cost') and also it has already @ property \XF\Entity\PaymentProfile $paymentProfile ;)
 

NikitOS

Well-known member
What if I need access on the PaymentProfile entity to fetch some values which will calculate the new price?
For cost to display? At that time, it is not clear what the cost will be, because several payment profiles can be used for the purchase. In any case, you can get the desired payment profile through the finder.
Is that possible to extend class Purchase implements \ArrayAccess? (XF\Purchasable\Purchase) ?
No.
 

Scandal

Active member
For cost to display? At that time, it is not clear what the cost will be, because several payment profiles can be used for the purchase. In any case, you can get the desired payment profile through the finder.

No.
Hi!
Yes I understand what you said, you're right.
The problem is the following:
ok, we changed the cost via purchaserequest save entity (Repository).
The issue: lots of other payment providers (developed by others), during hot functions like:
protected function getPaymentParams(PurchaseRequest $purchaseRequest, Purchase $purchase)
and
public function initiatePayment(Controller $controller, PurchaseRequest $purchaseRequest, Purchase $purchase)
and
public function processPayment(Controller $controller, PurchaseRequest $purchaseRequest, PaymentProfile $paymentProfile, Purchase $purchase)
... got the price (cost) via the $purchase->cost variable to initiate or process the payment to the service.

So currently I have to extend each provider's class to make something common with that you suggested for public function insertPurchaseRequest(XF\Purchasable\Purchase $purchase)
-> $purchase->cost = 123
-> return parent::

For this reason I was asking to extend the class Purchase implements \ArrayAccess class.
Is there any alternative way to modify the $purchase->cost more deeply on the php? I don't find it so normalized to extend each time the class of the custom payment providers and apply the new cost on the pre-noticed methods.

PS: I'm building a discount system based on payment profiles. This is the reason I need to modify the cost. :)
 
Last edited:

NikitOS

Well-known member
I have an add-on that changes the cost and currency for all payment providers and it changes those values in the insertPurchaseRequest repository function, and there is no problem with any payment providers.
 
Top