bryglen / yii2-braintree

braintree wrapper for yii 2
0 stars 5 forks source link

Issue Using Multi-Parameter Braintree Endpoints #3

Open sbrendtro opened 8 years ago

sbrendtro commented 8 years ago

Getting an error with a few of the Braintree endpoints that require two arguments (e.g. Subscription update()). In this case, the first argument is the subscription ID, and the second is the array of parameters with which to update the subscription.

Missing argument 2 for Braintree_Subscription::update() vendor/braintree/braintree_php/lib/Braintree/Subscription.php line: 86

call_user_func_array() might be a better choice to use in Braintree::call(), however it wouldn't necessarily be backwards compatible for current users of your library. I solved this locally using a modified version of call(). It is a bit "hacky", but it works (at least for the 2-parameter methods):

    public function call($command, $method, $values, $values2=null)
    {
        $class = strtr("{class}_{command}",array(
                '{class}' => $this->_prefix,
                '{command}' => $command,
            ));
        if ( $values2 )
            return call_user_func(array($class, $method), $values, $values2);
        else
            return call_user_func(array($class, $method), $values);
    }

Other endpoints that would be unusable without this fix (just to name a few):

Subscription::retryCharge($subscriptionId, $amount = null)
Subscription::fetch($query, $ids)
Transaction::cloneTransaction($transactionId, $attribs)
CreditCard::expiringBetween($startDate, $endDate)
CreditCard::credit($token, $transactionAttribs)
CreditCard::sale($token, $transactionAttribs)
CreditCard::saleNoValidate($token, $transactionAttribs)

Note that there are actually methods that take more than 2 parameters, and still would be broken with this fix:

CreditCard::fetchExpiring($startDate, $endDate, $ids)

(there may be more...)

bryglen commented 8 years ago

there can be a way without any breaking changes..

if (is_array($values)) {
   call_user_func_array()
] else {
   call_user_func()
}
sbrendtro commented 8 years ago

That makes sense, though it may need a bit more since some endpoints actually expect an array as their single parameter:

Braintree_ClientToken::generate($params=array()) Braintree_ClientToken::conditionallyVerifyKeys($params)

It could be called as ->call( 'ClientToken', 'generate', [ $params ] ), but that would be a slight change to how users are currently calling it. There are very few endpoints expecting an array for the param, but unfortunately most people are probably using the generate method in their work flow.

Thoughts? And thanks for the extension! Steve.

On Sun, Dec 6, 2015 at 12:39 AM, bryglen notifications@github.com wrote:

there can be a way without any breaking changes..

if (is_array($values)) { call_user_func_array()] else { call_user_func_array()}

— Reply to this email directly or view it on GitHub https://github.com/bryglen/yii2-braintree/issues/3#issuecomment-162279502 .