I have existing code that has been working fine with the former WooCommerce PayPal Payment Gateway, but now that this has been abandoned in favour of a new version, WooCommerce PayPal Payments I am getting a conflict with some custom code I am using to edit the headings of some custom fields I am using on the checkout page.
I used the solution provided here; ie:
// -- add heading type
add_filter( 'woocommerce_form_field_heading','wpwp_checkout_fields_heading', 99, 4 );
function wpwp_checkout_fields_heading($field, $key, $args, $value) {
$output = '<h3 class="form-row form-row-wide">'.__( $args['label'], 'woocommerce' ).'</h3>';
echo $output;
}
// -- modify checkout fields
add_action( 'woocommerce_checkout_fields', 'wpwp_checkout_fields', 10, 1 );
function wpwp_checkout_fields($fields) {
// add custom heading
$fields['billing']['billing_email_heading'] = array(
'type' => 'heading',
'label' => 'Contact Information'
);
$fields['billing']['billing_email_subscribe'] = array(
'type' => 'checkbox',
'label' => 'Keep me up to date on news and exclusive offers.',
'required' => false
);
$fields['billing']['billing_address_heading'] = array(
'type' => 'heading',
'label' => 'Billing address'
);
// rename billing fields
$fields['billing']['billing_address_1']['label'] = 'Address';
$fields['billing']['billing_city']['label'] = 'City';
// re-order billing fields
$fields['billing']['billing_email_heading']['priority'] = 10;
$fields['billing']['billing_email']['priority'] = 20;
$fields['billing']['billing_email_subscribe']['priority'] = 25;
$fields['billing']['billing_address_heading']['priority'] = 29;
$fields['billing']['billing_first_name']['priority'] = 30;
$fields['billing']['billing_last_name']['priority'] = 40;
$fields['billing']['billing_company']['priority'] = 45;
$fields['billing']['billing_address_1']['priority'] = 50;
$fields['billing']['billing_address_2']['priority'] = 60;
$fields['billing']['billing_city']['priority'] = 70;
$fields['billing']['billing_country']['priority'] = 80;
$fields['billing']['billing_state']['priority'] = 90;
$fields['billing']['billing_postcode']['priority'] = 100;
$fields['billing']['billing_phone']['priority'] = 110;
// Change certain fields to optional
$fields['billing']['billing_phone']['required'] = false;
// rename shipping fields
$fields['shipping']['shipping_address_1']['label'] = 'Address';
$fields['shipping']['shipping_city']['label'] = 'City';
// re-order shipping fields
$fields['shipping']['shipping_first_name']['priority'] = 20;
$fields['shipping']['shipping_last_name']['priority'] = 30;
$fields['shipping']['shipping_company']['priority'] = 35;
$fields['shipping']['shipping_address_1']['priority'] = 40;
$fields['shipping']['shipping_address_2']['priority'] = 50;
$fields['shipping']['shipping_city']['priority'] = 60;
$fields['shipping']['shipping_country']['priority'] = 70;
$fields['shipping']['shipping_state']['priority'] = 80;
$fields['shipping']['shipping_postcode']['priority'] = 90;
// add heading to order notes
$fields['order']['order_comments_heading'] = array(
'type' => 'heading',
'label' => 'Additional information'
);
// re-order order fields
$fields['order']['order_comments_heading']['priority'] = 10;
$fields['order']['order_comments']['priority'] = 20;
return $fields;
}
But when I go to the checkout page I get this error:
Fatal error: Uncaught TypeError: Return value of WooCommercePayPalCommerceWcGatewaySettingsSettingsRenderer::render_multiselect() must be of the type string, null returned in **************/wp-content/plugins/woocommerce-paypal-payments/modules/ppcp-wc-gateway/src/Settings/SettingsRenderer.php:198
The code for this section is:
/**
* Renders the multiselect field.
*
* @param string $field The current field HTML.
* @param string $key The current key.
* @param array $config The configuration array.
* @param string $value The current value.
*
* @return string
*/
public function render_multiselect( $field, $key, $config, $value ): string {
if ( 'ppcp-multiselect' !== $config['type'] ) {
return $field; // This is line 198
}
$options = array();
foreach ( $config['options'] as $option_key => $option_value ) {
$selected = ( in_array( $option_key, $value, true ) ) ? 'selected="selected"' : '';
$options[] = '<option value="' . esc_attr( $option_key ) . '" ' . $selected . '>' .
esc_html( $option_value ) .
'</option>';
}
$html = sprintf(
'<select
multiple
class="%s"
name="%s"
>%s</select>',
esc_attr( implode( ' ', isset( $config['input_class'] ) ? $config['input_class'] : array() ) ),
esc_attr( $key ) . '[]',
implode( '', $options )
);
return $html;
}
Line 198
is near the top of that code and I have inserted a comment denoting it.
In the below file from the new payment gateway plugin, which is located at wp-contentpluginswoocommerce-paypal-paymentsmodulesppcp-wc-gatewaysrcWCGatewayModule.php
I have found the below, which may be relevant:
add_filter(
'woocommerce_form_field',
static function ( $field, $key, $args, $value ) use ( $container ) {
$renderer = $container->get( 'wcgateway.settings.render' );
/**
* The Settings Renderer object.
*
* @var SettingsRenderer $renderer
*/
$field = $renderer->render_multiselect( $field, $key, $args, $value );
$field = $renderer->render_password( $field, $key, $args, $value );
$field = $renderer->render_text_input( $field, $key, $args, $value );
$field = $renderer->render_heading( $field, $key, $args, $value );
$field = $renderer->render_table( $field, $key, $args, $value );
return $field;
},
10,
4
);
Is there any problems in my code that I can do to fix this issue?
2
Answers
It appears the solution is that you have to
return
the output from the function that is called from the call to thewoocommerce_form_field_heading
filter, instead of echoing it.It seems my call to the
woocommerce_form_field_heading
filter conflicted with therender_multiselect
function call, which was called within the anonymous function listed above, in the call to thewoocommerce_form_field
filter:I'm not entirely sure how they interact, but I'm assuming that
woocommerce_form_field_heading
gets called during calls towoocommerce_form_field
and thus myecho
statement interrupted the flow, and thus me echo'ing the data, instead of returning it, ended up withnull
being returned, and not a string, of which produced the error.