File "PayPalCommerce.php"
Full Path: /home/buyiwexj/public_html/wp-content/plugins/wpforms-lite/src/Integrations/PayPalCommerce/Fields/PayPalCommerce.php
File size: 52.44 KB
MIME-type: text/x-php
Charset: utf-8
<?php
namespace WPForms\Integrations\PayPalCommerce\Fields;
use WPForms_Field;
use WPForms\Integrations\PayPalCommerce\Connection;
use WPForms\Integrations\PayPalCommerce\Helpers;
use WPForms\Integrations\PayPalCommerce\Integrations\Loader;
/**
* PayPal Commerce credit card field.
*
* @since 1.10.0
*/
class PayPalCommerce extends WPForms_Field {
/**
* Integrations loader instance.
*
* @since 1.10.0
*
* @var Loader
*/
private $integrations;
/**
* Determine if a new field was added.
*
* @since 1.10.0
*
* @var bool
*/
private $is_new_field = false;
/**
* Primary class constructor.
*
* @since 1.10.0
*/
public function init(): void {
// Define field type information.
$this->name = esc_html__( 'PayPal Commerce', 'wpforms-lite' );
$this->keywords = esc_html__( 'store, ecommerce, credit card, pay, payment, debit card', 'wpforms-lite' );
$this->type = 'paypal-commerce';
$this->icon = 'fa-credit-card';
$this->order = 89;
$this->group = 'payment';
$this->integrations = new Loader();
$this->hooks();
}
/**
* Register hooks.
*
* @since 1.10.0
*/
private function hooks(): void {
add_filter( 'wpforms_field_properties_paypal-commerce', [ $this, 'field_properties' ], 5, 3 );
add_filter( 'wpforms_field_new_required', [ $this, 'default_required' ], 10, 2 );
add_filter( 'wpforms_builder_field_button_attributes', [ $this, 'field_button_atts' ], 10, 3 );
add_filter( 'wpforms_field_new_display_duplicate_button', [ $this, 'field_display_duplicate_button' ], 10, 2 );
add_filter( 'wpforms_field_preview_display_duplicate_button', [ $this, 'field_display_duplicate_button' ], 10, 2 );
add_filter( 'wpforms_pro_fields_entry_preview_is_field_support_preview_paypal-commerce_field', [ $this, 'entry_preview_availability' ], 10, 4 );
add_filter( 'wpforms_field_display_sublabel_for', [ $this, 'modify_sublabel_for' ], 10, 3 );
add_filter( 'wpforms_frontend_foot_submit_classes', [ $this, 'submit_button_classes' ], 10, 2 );
add_action( 'wpforms_display_submit_after', [ $this, 'submit_button' ], 9, 2 );
}
/**
* Define additional field properties.
*
* @since 1.10.0
*
* @param array $properties Field properties.
* @param array $field Field settings.
* @param array $form_data Form data and settings.
*
* @return array
*
* @noinspection PhpMissingParamTypeInspection
*/
public function field_properties( $properties, array $field, array $form_data ): array { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh
$properties = (array) $properties;
// Remove primary for expanded formats since we have first, middle, last.
// Remove for attribute from the label as there is no id for it.
unset( $properties['inputs']['primary'], $properties['label']['attr']['for'] );
if ( ! isset( $field['credit_card'] ) ) {
$is_fastlane_only = isset( $field['fastlane'] ) && empty( $field['paypal_checkout'] );
$properties['container']['class'][] = 'wpforms-field-paypal-commerce';
$properties['label']['disabled'] = ! $is_fastlane_only && empty( $field['description'] );
return $properties;
}
$default_labels = $this->get_default_labels();
$form_id = absint( $form_data['id'] );
$field_id = absint( $field['id'] );
$is_card_holder_enable = isset( $field['card_holder_enable'] );
$props = [
'inputs' => [
'number' => [
'attr' => [
'name' => '',
'value' => '',
],
'block' => [
'wpforms-field-paypal-commerce-number',
],
'class' => [
'wpforms-field-paypal-commerce-cardnumber',
],
'data' => [],
'id' => "wpforms-{$form_id}-field_{$field_id}-cardnumber",
'required' => ! empty( $field['required'] ) ? 'required' : '',
'sublabel' => [
'hidden' => ! empty( $field['sublabel_hide'] ),
'value' => ! empty( $field['card_number'] ) ? esc_html( $field['card_number'] ) : $default_labels['card_number'],
'position' => 'after',
],
],
'date' => [
'attr' => [
'name' => '',
'value' => '',
],
'block' => [
'wpforms-field-paypal-commerce-date',
],
'class' => [
'wpforms-field-paypal-commerce-carddate',
],
'data' => [],
'id' => "wpforms-{$form_id}-field_{$field_id}-carddate",
'required' => ! empty( $field['required'] ) ? 'required' : '',
'sublabel' => [
'hidden' => ! empty( $field['sublabel_hide'] ),
'value' => ! empty( $field['expiration_date'] ) ? esc_html( $field['expiration_date'] ) : $default_labels['expiration_date'],
'position' => 'after',
],
],
'code' => [
'attr' => [
'name' => '',
'value' => '',
],
'block' => [
'wpforms-field-paypal-commerce-code',
],
'class' => [
'wpforms-field-paypal-commerce-cardcode',
],
'data' => [],
'id' => "wpforms-{$form_id}-field_{$field_id}-cardcode",
'required' => ! empty( $field['required'] ) ? 'required' : '',
'sublabel' => [
'hidden' => ! empty( $field['sublabel_hide'] ),
'value' => ! empty( $field['security_code'] ) ? esc_html( $field['security_code'] ) : $default_labels['security_code'],
'position' => 'after',
],
],
],
];
if ( $is_card_holder_enable ) {
$props['inputs']['name'] = [
'attr' => [
'name' => "wpforms[fields][{$field_id}][cardname]",
'placeholder' => ! empty( $field['cardname_placeholder'] ) ? $field['cardname_placeholder'] : '',
],
'block' => [
'wpforms-field-paypal-commerce-name',
],
'class' => [
'wpforms-field-paypal-commerce-cardname',
],
'data' => [],
'id' => "wpforms-{$form_id}-field_{$field_id}-cardname",
'required' => ! empty( $field['required'] ) ? 'required' : '',
'sublabel' => [
'hidden' => ! empty( $field['sublabel_hide'] ),
'value' => ! empty( $field['card_holder_name'] ) ? esc_html( $field['card_holder_name'] ) : $default_labels['card_holder_name'],
'position' => 'after',
],
];
}
$properties = array_merge_recursive( $properties, $props );
// If this field is required, we need to make some adjustments.
if ( ! empty( $field['required'] ) ) {
// Add the required class if needed (for multipage validation).
$properties['inputs']['number']['class'][] = 'wpforms-field-required';
$properties['inputs']['date']['class'][] = 'wpforms-field-required';
$properties['inputs']['code']['class'][] = 'wpforms-field-required';
if ( $is_card_holder_enable ) {
$properties['inputs']['name']['class'][] = 'wpforms-field-required';
}
}
return $properties;
}
/**
* Default to the required.
*
* @since 1.10.0
*
* @param bool $required Required status, true if required.
* @param array $field Field settings.
*
* @return bool
*
* @noinspection PhpMissingParamTypeInspection
*/
public function default_required( $required, array $field ): bool {
if ( $this->type !== $field['type'] ) {
return (bool) $required;
}
$this->is_new_field = true;
return true;
}
/**
* Define additional "Add Field" button attributes.
*
* @since 1.10.0
*
* @param array $atts Add Field button attributes.
* @param array $field Field settings.
* @param array $form_data Form data and settings.
*
* @return array
*
* @noinspection PhpMissingParamTypeInspection
*/
public function field_button_atts( $atts, array $field, array $form_data ): array {
if ( $field['type'] !== $this->type ) {
return $atts;
}
if ( Helpers::has_paypal_commerce_field( $form_data ) ) {
$atts['atts']['disabled'] = 'true';
$atts['class'][] = 'wpforms-add-fields-button-disabled';
return $atts;
}
if ( Connection::get() ) {
return $atts;
}
$atts['class'][] = 'warning-modal';
$atts['class'][] = 'paypal-commerce-connection-required';
return $atts;
}
/**
* Disallow a field preview "Duplicate" button.
*
* @since 1.10.0
*
* @param bool $display Display switch.
* @param array $field Field settings.
*
* @return bool
*
* @noinspection PhpMissingParamTypeInspection
*/
public function field_display_duplicate_button( $display, array $field ): bool {
$display = (bool) $display;
return $field['type'] === $this->type ? false : $display;
}
/**
* The field value availability for the Entry Preview field.
*
* @since 1.10.0
*
* @param bool $is_supported The field availability.
* @param string $value The submitted Credit Card detail.
* @param array $field Field data.
* @param array $form_data Form data.
*
* @return bool
*
* @noinspection PhpMissingParamTypeInspection
* @noinspection PhpUnusedParameterInspection
*/
public function entry_preview_availability( $is_supported, $value, $field, $form_data ): bool {
return ! empty( $value );
}
/**
* Disallow dynamic population.
*
* @since 1.10.0
*
* @param array $properties Field properties.
* @param array $field Current field specific data.
*
* @return bool
*/
public function is_dynamic_population_allowed( $properties, $field ): bool {
return false;
}
/**
* Disallow fallback population.
*
* @since 1.10.0
*
* @param array $properties Field properties.
* @param array $field Current field specific data.
*
* @return bool
*/
public function is_fallback_population_allowed( $properties, $field ): bool {
return false;
}
/**
* Field options panel inside the builder.
*
* @since 1.10.0
*
* @param array $field Field settings.
*/
public function field_options( $field ): void {
$this->basic_options( $field );
$this->advanced_options( $field );
}
/**
* Basic options.
*
* @since 1.10.0
*
* @param array $field Current field specific data.
*/
private function basic_options( array $field ): void {
$this->field_option( 'basic-options', $field, [ 'markup' => 'open' ] );
$this->field_option( 'label', $field );
$this->field_option( 'description', $field );
$this->payment_methods_options( $field );
$this->supported_credit_cards_options( $field );
$this->sublabels_options( $field );
$this->fastlane_labels_options( $field );
$this->field_option( 'required', $field );
$this->field_option( 'basic-options', $field, [ 'markup' => 'close' ] );
}
/**
* Advanced options.
*
* @since 1.10.0
*
* @param array $field Current field specific data.
*/
private function advanced_options( array $field ): void {
$this->field_option( 'advanced-options', $field, [ 'markup' => 'open' ] );
$this->field_option( 'size', $field );
$this->button_size_option( $field );
$this->shape_option( $field );
$this->color_option( $field );
$this->field_option( 'css', $field );
$this->field_option( 'label_hide', $field );
$this->field_option( 'advanced-options', $field, [ 'markup' => 'close' ] );
}
/**
* Button size option.
*
* @since 1.10.0
*
* @param array $field Current field specific data.
*/
private function button_size_option( array $field ): void {
$output = $this->field_element(
'label',
$field,
[
'slug' => 'button_size',
'value' => esc_html__( 'Button Size', 'wpforms-lite' ),
'tooltip' => esc_html__( 'PayPal checkout button size.', 'wpforms-lite' ),
],
false
);
$output .= $this->field_element(
'select',
$field,
[
'slug' => 'button_size',
'value' => ! empty( $field['button_size'] ) ? esc_attr( $field['button_size'] ) : '',
'options' => [
'responsive' => esc_html__( 'Responsive', 'wpforms-lite' ),
'small' => esc_html__( 'Small', 'wpforms-lite' ),
'medium' => esc_html__( 'Medium', 'wpforms-lite' ),
'large' => esc_html__( 'Large', 'wpforms-lite' ),
],
],
false
);
$this->field_element(
'row',
$field,
[
'slug' => 'button_size',
'content' => $output,
]
);
}
/**
* Shape option.
*
* @since 1.10.0
*
* @param array $field Current field specific data.
*/
private function shape_option( array $field ): void {
$output = $this->field_element(
'label',
$field,
[
'slug' => 'shape',
'value' => esc_html__( 'Button Shape', 'wpforms-lite' ),
'tooltip' => esc_html__( 'PayPal checkout button shape.', 'wpforms-lite' ),
],
false
);
$output .= $this->field_element(
'select',
$field,
[
'slug' => 'shape',
'value' => ! empty( $field['shape'] ) ? esc_attr( $field['shape'] ) : '',
'options' => [
'pill' => esc_html__( 'Pill', 'wpforms-lite' ),
'rect' => esc_html__( 'Rectangle', 'wpforms-lite' ),
],
],
false
);
$this->field_element(
'row',
$field,
[
'slug' => 'shape',
'content' => $output,
]
);
}
/**
* Color option.
*
* @since 1.10.0
*
* @param array $field Current field specific data.
*/
private function color_option( array $field ): void {
$output = $this->field_element(
'label',
$field,
[
'slug' => 'color',
'value' => esc_html__( 'Button Color', 'wpforms-lite' ),
'tooltip' => esc_html__( 'PayPal checkout button color.', 'wpforms-lite' ),
],
false
);
$output .= $this->field_element(
'select',
$field,
[
'slug' => 'color',
'value' => ! empty( $field['color'] ) ? esc_attr( $field['color'] ) : '',
'options' => [
'blue' => esc_html__( 'Blue', 'wpforms-lite' ),
'black' => esc_html__( 'Black', 'wpforms-lite' ),
'white' => esc_html__( 'White', 'wpforms-lite' ),
'gold' => esc_html__( 'Gold', 'wpforms-lite' ),
'silver' => esc_html__( 'Silver', 'wpforms-lite' ),
],
],
false
);
$this->field_element(
'row',
$field,
[
'slug' => 'color',
'content' => $output,
]
);
}
/**
* Display payment methods options.
*
* @since 1.10.0
*
* @param array $field Current field specific data.
*/
private function payment_methods_options( array $field ): void {
// Ensure Credit Card and Fastlane are not both enabled, prefer Credit Card and disable Fastlane if both are enabled.
if ( ! empty( $field['credit_card'] ) && ! empty( $field['fastlane'] ) ) {
unset( $field['fastlane'] );
if ( ! empty( $field['default_method'] ) && $field['default_method'] === 'fastlane' ) {
$field['default_method'] = 'credit_card';
}
}
$payment_methods = $this->field_element(
'label',
$field,
[
'slug' => 'payment_methods',
'value' => esc_html__( 'Supported Payment Methods', 'wpforms-lite' ),
'tooltip' => esc_html__( 'Select payment methods to enable.', 'wpforms-lite' ),
],
false
);
$payment_methods .= $this->field_element(
'toggle',
$field,
[
'slug' => 'paypal_checkout',
'value' => isset( $field['paypal_checkout'] ) || $this->is_new_field ? '1' : '0',
'desc' => esc_html__( 'PayPal Checkout', 'wpforms-lite' ),
'class' => 'wpforms-field-option-paypal-checkout',
],
false
);
$payment_methods .= $this->field_element(
'toggle',
$field,
[
'slug' => 'credit_card',
'value' => isset( $field['credit_card'] ) || $this->is_new_field ? '1' : '0',
'desc' => esc_html__( 'Credit Card', 'wpforms-lite' ),
'class' => 'wpforms-field-option-credit-card',
],
false
);
$payment_methods .= $this->field_element(
'toggle',
$field,
[
'slug' => 'fastlane',
'value' => isset( $field['fastlane'] ) ? '1' : '0',
'desc' => esc_html__( 'Fastlane', 'wpforms-lite' ),
'class' => 'wpforms-field-option-fastlane',
],
false
);
$this->field_element(
'row',
$field,
[
'slug' => 'payment_methods',
'content' => $payment_methods,
]
);
$default_method_field = $this->field_element(
'label',
$field,
[
'slug' => 'default_method',
'value' => esc_html__( 'Default Payment Method', 'wpforms-lite' ),
'tooltip' => esc_html__( 'Select the default payment method.', 'wpforms-lite' ),
],
false
);
$default_method_field .= $this->field_element(
'select',
$field,
[
'slug' => 'default_method',
'value' => ! empty( $field['default_method'] ) ? esc_attr( $field['default_method'] ) : '',
'options' => [
'paypal_checkout' => esc_html__( 'PayPal Checkout', 'wpforms-lite' ),
'credit_card' => esc_html__( 'Credit Card', 'wpforms-lite' ),
'fastlane' => esc_html__( 'Fastlane', 'wpforms-lite' ),
],
],
false
);
// Show toggle when two and more options are available.
$hidden_class = ( (int) ! empty( $field['paypal_checkout'] ) + (int) ! empty( $field['credit_card'] ) + (int) ! empty( $field['fastlane'] ) ) < 2;
$this->field_element(
'row',
$field,
[
'slug' => 'default_method',
'content' => $default_method_field,
'class' => $hidden_class && ! $this->is_new_field ? 'wpforms-hidden' : '',
]
);
}
/**
* Display supported credit cards options.
*
* @since 1.10.0
*
* @param array $field Current field specific data.
*/
private function supported_credit_cards_options( array $field ): void {
$credit_cards = $this->field_element(
'label',
$field,
[
'slug' => 'credit_cards',
'value' => esc_html__( 'Supported Credit Cards', 'wpforms-lite' ),
'tooltip' => esc_html__( 'Select supported credit cards.', 'wpforms-lite' ),
],
false
);
$credit_cards .= $this->field_element(
'toggle',
$field,
[
'slug' => 'amex',
'value' => isset( $field['amex'] ) || $this->is_new_field ? '1' : '0',
'desc' => esc_html__( 'American Express', 'wpforms-lite' ),
'data' => [ 'card' => 'amex' ],
],
false
);
$credit_cards .= $this->field_element(
'toggle',
$field,
[
'slug' => 'discover',
'value' => isset( $field['discover'] ) || $this->is_new_field ? '1' : '0',
'desc' => esc_html__( 'Discover', 'wpforms-lite' ),
'data' => [ 'card' => 'discover' ],
],
false
);
$credit_cards .= $this->field_element(
'toggle',
$field,
[
'slug' => 'maestro',
'value' => isset( $field['maestro'] ) && ! $this->is_new_field ? '1' : '0',
'desc' => esc_html__( 'Maestro', 'wpforms-lite' ),
'data' => [ 'card' => 'maestro' ],
],
false
);
$credit_cards .= $this->field_element(
'toggle',
$field,
[
'slug' => 'mastercard',
'value' => isset( $field['mastercard'] ) || $this->is_new_field ? '1' : '0',
'desc' => esc_html__( 'Mastercard', 'wpforms-lite' ),
'data' => [ 'card' => 'mastercard' ],
],
false
);
$credit_cards .= $this->field_element(
'toggle',
$field,
[
'slug' => 'visa',
'value' => isset( $field['visa'] ) || $this->is_new_field ? '1' : '0',
'desc' => esc_html__( 'Visa', 'wpforms-lite' ),
'data' => [ 'card' => 'visa' ],
],
false
);
$this->field_element(
'row',
$field,
[
'slug' => 'credit_cards',
'content' => $credit_cards,
'class' => ! isset( $field['credit_card'] ) && ! $this->is_new_field ? 'wpforms-hidden' : '',
]
);
}
/**
* Display sublabel_options options.
*
* @since 1.10.0
*
* @param array $field Current field specific data.
*/
private function sublabels_options( array $field ): void {
$default_labels = $this->get_default_labels();
$sublabels = $this->field_element(
'label',
$field,
[
'slug' => 'sublabels',
'value' => esc_html__( 'Sublabels', 'wpforms-lite' ),
'tooltip' => esc_html__( 'Additional credit card fields.', 'wpforms-lite' ),
],
false
);
$card_number = $this->field_element(
'text',
$field,
[
'slug' => 'card_number',
'value' => ! empty( $field['card_number'] ) ? esc_attr( $field['card_number'] ) : '',
'before' => $default_labels['card_number'],
'placeholder' => $default_labels['card_number'],
'data' => [ 'sublabel' => 'card-number' ],
],
false
);
$sublabels .= $this->field_element(
'row',
$field,
[
'slug' => 'card_number',
'content' => $card_number,
],
false
);
$expiration_date = $this->field_element(
'text',
$field,
[
'slug' => 'expiration_date',
'value' => ! empty( $field['expiration_date'] ) ? esc_attr( $field['expiration_date'] ) : '',
'before' => $default_labels['expiration_date'],
'placeholder' => $default_labels['expiration_date'],
'data' => [ 'sublabel' => 'expiration-date' ],
],
false
);
$sublabels .= $this->field_element(
'row',
$field,
[
'slug' => 'expiration_date',
'content' => $expiration_date,
],
false
);
$security_code = $this->field_element(
'text',
$field,
[
'slug' => 'security_code',
'value' => ! empty( $field['security_code'] ) ? esc_attr( $field['security_code'] ) : '',
'before' => $default_labels['security_code'],
'placeholder' => $default_labels['security_code'],
'data' => [ 'sublabel' => 'security-code' ],
],
false
);
$sublabels .= $this->field_element(
'row',
$field,
[
'slug' => 'security_code',
'content' => $security_code,
],
false
);
$card_holder = $this->field_element(
'toggle',
$field,
[
'slug' => 'card_holder_enable',
'value' => isset( $field['card_holder_enable'] ) || $this->is_new_field ? '1' : '0',
'desc' => $default_labels['card_holder_name'],
],
false
);
$card_holder .= $this->field_element(
'text',
$field,
[
'slug' => 'card_holder_name',
'value' => ! empty( $field['card_holder_name'] ) ? esc_attr( $field['card_holder_name'] ) : '',
'placeholder' => $default_labels['card_holder_name'],
'class' => ! isset( $field['card_holder_enable'] ) && ! $this->is_new_field ? 'wpforms-hidden' : '',
'data' => [ 'sublabel' => 'card-holder-name' ],
],
false
);
$sublabels .= $this->field_element(
'row',
$field,
[
'slug' => 'card_holder',
'content' => $card_holder,
],
false
);
$this->field_element(
'row',
$field,
[
'slug' => 'sublabels',
'content' => $sublabels,
'class' => ! isset( $field['credit_card'] ) && ! $this->is_new_field ? 'wpforms-hidden' : '',
]
);
}
/**
* Display Fastlane labels options.
*
* @since 1.10.0
*
* @param array $field Current field specific data.
*/
private function fastlane_labels_options( array $field ): void {
$default_labels = $this->get_default_labels();
$labels = $this->field_element(
'label',
$field,
[
'slug' => 'fastlane_labels',
'value' => esc_html__( 'Fastlane Labels', 'wpforms-lite' ),
'tooltip' => esc_html__( 'Customize Fastlane email placeholder and button text.', 'wpforms-lite' ),
],
false
);
$email_placeholder = $this->field_element(
'text',
$field,
[
'slug' => 'fastlane_email_placeholder',
'value' => ! empty( $field['fastlane_email_placeholder'] ) ? esc_attr( $field['fastlane_email_placeholder'] ) : '',
'before' => $default_labels['fastlane_email_placeholder'],
'placeholder' => $default_labels['fastlane_email_placeholder'],
'data' => [ 'fastlane' => 'email-placeholder' ],
],
false
);
$labels .= $this->field_element(
'row',
$field,
[
'slug' => 'fastlane_email_placeholder',
'content' => $email_placeholder,
],
false
);
$continue_label = $this->field_element(
'text',
$field,
[
'slug' => 'fastlane_continue_label',
'value' => ! empty( $field['fastlane_continue_label'] ) ? esc_attr( $field['fastlane_continue_label'] ) : '',
'before' => $default_labels['fastlane_continue_label'],
'placeholder' => $default_labels['fastlane_continue_label'],
'data' => [ 'fastlane' => 'continue-label' ],
],
false
);
$labels .= $this->field_element(
'row',
$field,
[
'slug' => 'fastlane_continue_label',
'content' => $continue_label,
],
false
);
$this->field_element(
'row',
$field,
[
'slug' => 'fastlane_labels',
'content' => $labels,
'class' => ! isset( $field['fastlane'] ) && ! $this->is_new_field ? 'wpforms-hidden' : '',
]
);
}
/**
* Get default labels.
*
* @since 1.10.0
*
* @return array
*/
private function get_default_labels(): array {
return [
'card_number' => __( 'Card Number', 'wpforms-lite' ),
'expiration_date' => __( 'Expiration Date', 'wpforms-lite' ),
'security_code' => __( 'Security Code', 'wpforms-lite' ),
'card_holder_name' => __( 'Card Holder Name', 'wpforms-lite' ),
'fastlane_email_placeholder' => __( 'Email', 'wpforms-lite' ),
'fastlane_continue_label' => __( 'Continue', 'wpforms-lite' ),
];
}
/**
* Field preview inside the builder.
*
* @since 1.10.0
*
* @param array $field Field settings.
*/
public function field_preview( $field ): void { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh
$default_labels = $this->get_default_labels();
// Define data.
$name_label = ! empty( $field['card_holder_name'] ) ? $field['card_holder_name'] : $default_labels['card_holder_name'];
$code_label = ! empty( $field['security_code'] ) ? $field['security_code'] : $default_labels['security_code'];
$date_label = ! empty( $field['expiration_date'] ) ? $field['expiration_date'] : $default_labels['expiration_date'];
$card_label = ! empty( $field['card_number'] ) ? $field['card_number'] : $default_labels['card_number'];
$fastlane_email_placeholder = ! empty( $field['fastlane_email_placeholder'] ) ? $field['fastlane_email_placeholder'] : $default_labels['fastlane_email_placeholder'];
$fastlane_continue_label = ! empty( $field['fastlane_continue_label'] ) ? $field['fastlane_continue_label'] : $default_labels['fastlane_continue_label'];
// What methods are enabled?
$has_cc = ! empty( $field['credit_card'] );
$has_checkout = ! empty( $field['paypal_checkout'] );
$has_fastlane = ! empty( $field['fastlane'] );
$enabled_count = (int) $has_cc + (int) $has_checkout + (int) $has_fastlane;
// Resolve the effective default method.
$effective_default = $this->resolve_default_method( (array) $field );
// Selected method label for the (readonly) dropdown.
$labels = [
'paypal_checkout' => __( 'PayPal Checkout', 'wpforms-lite' ),
'credit_card' => __( 'Credit Card', 'wpforms-lite' ),
'fastlane' => __( 'Fastlane', 'wpforms-lite' ),
];
$selected_method_label = $labels[ $effective_default ] ?? $labels['paypal_checkout'];
// Visibility booleans derived from the effective default.
$show_method_select = $enabled_count >= 2 || $this->is_new_field; // show only when multiple methods are enabled or for new field.
$show_fastlane = $has_fastlane && $effective_default === 'fastlane';
$show_credit_card = $has_cc && $effective_default === 'credit_card';
$show_checkout_warn = $has_checkout && ( ! $has_cc && ! $has_fastlane );
// Label.
$this->field_preview_option( 'label', $field );
?>
<div class="format-selected format-selected-full">
<div class="wpforms-paypal-commerce-payment-method <?php echo $show_method_select ? '' : 'wpforms-hidden'; ?>">
<select class="primary-input" readonly>
<option><?php echo esc_html( $selected_method_label ); ?></option>
</select>
</div>
<p class="wpforms-alert wpforms-alert-danger wpforms-paypal-commerce-no-payment-method-warning <?php echo isset( $field['paypal_checkout'] ) || isset( $field['credit_card'] ) || isset( $field['fastlane'] ) || $this->is_new_field ? 'wpforms-hidden' : ''; ?>"><?php esc_html_e( 'Please enable at least one payment method.', 'wpforms-lite' ); ?></p>
<p class="wpforms-alert wpforms-alert-warning wpforms-paypal-commerce-paypal-checkout-warning <?php echo ( $show_checkout_warn && ! $this->is_new_field ) ? '' : 'wpforms-hidden'; ?>"><?php esc_html_e( 'PayPal Checkout is enabled. The form’s submit button has been replaced by PayPal’s smart buttons.', 'wpforms-lite' ); ?></p>
<div class="wpforms-paypal-commerce-credit-card-fields <?php echo ( $show_credit_card ) ? '' : 'wpforms-hidden'; ?>">
<p class="wpforms-alert wpforms-alert-danger wpforms-paypal-commerce-no-credit-card-type-warning <?php echo isset( $field['amex'] ) || isset( $field['discover'] ) || isset( $field['maestro'] ) || isset( $field['mastercard'] ) || isset( $field['visa'] ) || $this->is_new_field ? 'wpforms-hidden' : ''; ?>"><?php esc_html_e( 'Please enable at least one credit card type.', 'wpforms-lite' ); ?></p>
<div class="wpforms-field-row">
<div class="wpforms-paypal-commerce-supported-cards">
<div class="wpforms-paypal-commerce-amex-icon <?php echo ! isset( $field['amex'] ) && ! $this->is_new_field ? 'wpforms-hidden' : ''; ?>"></div>
<div class="wpforms-paypal-commerce-discover-icon <?php echo ! isset( $field['discover'] ) && ! $this->is_new_field ? 'wpforms-hidden' : ''; ?>"></div>
<div class="wpforms-paypal-commerce-maestro-icon <?php echo ! isset( $field['maestro'] ) || $this->is_new_field ? 'wpforms-hidden' : ''; ?>"></div>
<div class="wpforms-paypal-commerce-mastercard-icon <?php echo ! isset( $field['mastercard'] ) && ! $this->is_new_field ? 'wpforms-hidden' : ''; ?>"></div>
<div class="wpforms-paypal-commerce-visa-icon <?php echo ! isset( $field['visa'] ) && ! $this->is_new_field ? 'wpforms-hidden' : ''; ?>"></div>
</div>
</div>
<div class="wpforms-field-row">
<div class="wpforms-paypal-commerce-card-number">
<input type="text" readonly>
<label class="wpforms-sub-label"><?php echo esc_html( $card_label ); ?></label>
</div>
</div>
<div class="wpforms-field-row">
<div class="wpforms-paypal-commerce-expiration-date wpforms-one-half">
<input type="text" readonly>
<label class="wpforms-sub-label"><?php echo esc_html( $date_label ); ?></label>
</div>
<div class="wpforms-paypal-commerce-security-code wpforms-one-half last">
<input type="text" readonly>
<label class="wpforms-sub-label"><?php echo esc_html( $code_label ); ?></label>
</div>
</div>
<div class="wpforms-field-row">
<div class="wpforms-paypal-commerce-card-holder-name <?php echo ! isset( $field['card_holder_enable'] ) && ! $this->is_new_field ? 'wpforms-hidden' : ''; ?>">
<input type="text" readonly>
<label class="wpforms-sub-label"><?php echo esc_html( $name_label ); ?></label>
</div>
</div>
</div>
<div class="wpforms-paypal-commerce-fastlane-fields <?php echo ( $show_fastlane ) ? '' : 'wpforms-hidden'; ?>">
<div class="wpforms-field-row">
<div class="wpforms-paypal-commerce-fastlane-container">
<div class="wpforms-paypal-commerce-fastlane-email-container">
<input type="email" placeholder="<?php echo esc_attr( $fastlane_email_placeholder ); ?>" readonly>
<div class="wpforms-paypal-commerce-fastlane-watermark"></div>
</div>
<div class="wpforms-paypal-commerce-fastlane-continue-container">
<button type="button" class="wpforms-paypal-commerce-fastlane-email-continue wpforms-page-button" title="<?php echo esc_attr( $fastlane_continue_label ); ?>"><?php echo esc_html( $fastlane_continue_label ); ?></button>
</div>
</div>
</div>
</div>
</div>
<?php
// Description.
$this->field_preview_option( 'description', $field );
}
/**
* Resolve the effective default payment method based on field settings.
*
* Prefers an explicit default_method when provided. If not provided and only one.
* method is enabled, that method becomes the default. Falls back to PayPal Checkout.
*
* @since 1.10.0
*
* @param array $field Field data and settings.
*
* @return string One of 'paypal_checkout', 'credit_card', or 'fastlane'.
*/
private function resolve_default_method( array $field ): string {
$has_cc = ! empty( $field['credit_card'] );
$has_checkout = ! empty( $field['paypal_checkout'] );
$has_fastlane = ! empty( $field['fastlane'] );
// Honor explicit default only if that method is enabled.
if ( ! empty( $field['default_method'] ) ) {
$dm = $field['default_method'];
if (
( $dm === 'paypal_checkout' && $has_checkout ) ||
( $dm === 'credit_card' && $has_cc ) ||
( $dm === 'fastlane' && $has_fastlane )
) {
return $dm;
}
}
if ( $has_cc ) {
return 'credit_card';
}
if ( $has_fastlane ) {
return 'fastlane';
}
// Fallback preference among enabled methods.
if ( $has_checkout ) {
return 'paypal_checkout';
}
// Default ultimate fallback.
return 'paypal_checkout';
}
/**
* Add submit button.
*
* @since 1.10.0
*
* @param array $form_data Form data and settings.
* @param string $button Button type.
*/
public function submit_button( array $form_data, string $button = '' ): void {
if ( $button !== 'submit' ) {
return;
}
if ( wpforms_is_admin_page( 'builder' ) ) {
$this->builder_submit_button( $form_data );
return;
}
// If not on the integration page (Divi / Elementor / Block Editor), display the frontend submit button.
// If on the integration page and credit card method were selected, return without action.
// Otherwise, display the builder submit button.
if ( ! $this->integrations->is_integration_page_loaded() ) {
$this->frontend_submit_button( $form_data );
return;
}
if ( $this->is_credit_card_method_selected( $form_data['fields'] ) ) {
return;
}
$this->builder_submit_button( $form_data );
}
/**
* Add the submit button hidden class.
*
* @since 1.10.0
*
* @param array $classes Button classes.
* @param array $form_data Form data and settings.
*
* @return array
*
* @noinspection PhpMissingParamTypeInspection
*/
public function submit_button_classes( $classes, array $form_data ): array {
$classes = (array) $classes;
if ( ! $this->integrations->is_integration_page_loaded() ) {
return $classes;
}
if ( $this->is_credit_card_method_selected( $form_data['fields'] ) ) {
return $classes;
}
$classes[] = 'wpforms-hidden';
return $classes;
}
/**
* Check if a credit card method is selected for the field.
*
* @since 1.10.0
*
* @param array $fields Form fields data.
*
* @return bool
*/
private function is_credit_card_method_selected( array $fields ): bool {
$field = Helpers::get_paypal_field( $fields );
return empty( $field['paypal_checkout'] ) ||
( ! empty( $field['credit_card'] ) && $field['default_method'] === 'credit_card' ) ||
( ! empty( $field['conditional_logic'] ) && $field['conditional_type'] === 'show' );
}
/**
* Display a 'submit' button on the builder.
*
* @since 1.10.0
*
* @param array $form_data Form data and settings.
*/
private function builder_submit_button( array $form_data ): void {
if ( ! isset( $form_data['fields'] ) ) {
return;
}
$field = Helpers::get_paypal_field( $form_data['fields'] );
if ( ! isset( $field['shape'] ) ) {
$field['shape'] = 'pill';
}
if ( ! isset( $field['color'] ) ) {
$field['color'] = 'blue';
}
$wrapper_hide = isset( $field['paypal_checkout'] ) && ! empty( $form_data['fields'] ) ? '' : 'wpforms-hidden';
$size_class = ! isset( $field['button_size'] ) || $field['button_size'] === 'responsive' ? 'size-medium' : 'size-' . $field['button_size'];
?>
<div id="wpforms-paypal-commerce-buttons-wrapper" class="<?php echo esc_attr( implode( ' ', [ $wrapper_hide, $size_class ] ) ); ?>">
<?php
/**
* Fires after the PayPal Commerce checkout button in the form builder.
*
* @since 1.10.0
*
* @param array $field PayPal Commerce field data.
*/
do_action( 'wpforms_integrations_paypal_commerce_fields_paypal_commerce_builder_submit_button', $field ); // phpcs:ignore WPForms.PHP.ValidateHooks.InvalidHookName
?>
</div>
<?php
}
/**
* Display a 'submit' button on the form front-end.
*
* @since 1.10.0
*
* @param array $form_data Form data and settings.
*/
private function frontend_submit_button( array $form_data ): void {
$connection = Connection::get();
if ( ! $connection ||
! $connection->is_usable() ||
! Helpers::is_paypal_commerce_enabled( $form_data ) ||
! Helpers::is_subscriptions_configured( $form_data )
) {
return;
}
$field = Helpers::get_paypal_field( $form_data['fields'] );
if ( empty( $field ) ) {
return;
}
if ( ! isset( $field['credit_card'] ) && ! isset( $field['paypal_checkout'] ) ) {
return;
}
$this->render_submit_button_container( 'single', $form_data, $field, $connection );
$this->render_submit_button_container( 'subscriptions', $form_data, $field, $connection );
}
/**
* Get submit spinner html.
*
* @since 1.10.0
*
* @param array $form_data Form data and settings.
* @param string $class_name Spinner class.
*
* @return string
* @noinspection HtmlUnknownTarget
*/
private function get_submit_spinner( array $form_data, string $class_name ): string {
/** This filter is documented in includes/class-frontend.php. */
$src = apply_filters( 'wpforms_display_submit_spinner_src', WPFORMS_PLUGIN_URL . 'assets/images/submit-spin.svg', $form_data ); // phpcs:ignore WPForms.PHP.ValidateHooks.InvalidHookName
return sprintf(
'<img src="%s" class="%s" style="display: none;" width="26" height="26" alt="%s">',
esc_url( $src ),
esc_attr( $class_name ),
esc_attr__( 'Loading', 'wpforms-lite' )
);
}
/**
* Render submit button container.
*
* @since 1.10.0
*
* @param string $type Button type: 'single' or 'subscription'.
* @param array $form_data Form data and settings.
* @param array $field Current field specific data.
* @param object $connection PayPal connection data.
*/
private function render_submit_button_container( string $type, array $form_data, array $field, object $connection ): void {
if ( ! in_array( $type, [ 'single', 'subscriptions' ], true ) ) {
return;
}
$spinner_type = $type === 'single' ? 'single' : 'recurring';
$spinner = $this->get_submit_spinner( $form_data, "wpforms-paypal-commerce-{$spinner_type}-spinner" );
$size_class = ! isset( $field['button_size'] ) || $field['button_size'] === 'responsive' ? 'size-medium' : 'size-' . $field['button_size'];
printf( '<div class="%s %s">', esc_attr( "wpforms-paypal-commerce-{$type}-submit-button" ), esc_attr( $size_class ) );
echo $spinner; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
/**
* Fires after PayPal Commerce submit buttons are rendered.
*
* Allows payment sources to add their button containers.
*
* @since 1.10.0
*
* @param array $field Current field specific data.
* @param array $connection PayPal connection data.
*/
do_action( "wpforms_integrations_paypal_commerce_fields_paypal_commerce_{$type}_submit_button", $field, $connection ); // phpcs:ignore WPForms.PHP.ValidateHooks.InvalidHookName
echo '</div>';
}
/**
* Field display on the form front-end.
*
* @since 1.10.0
*
* @param array $field Field data and settings.
* @param array $deprecated Deprecated field attributes. Use field properties.
* @param array $form_data Form data and settings.
*/
public function field_display( $field, $deprecated, $form_data ): void {
// Display warning for non SSL pages.
if ( ! is_ssl() ) {
echo '<div class="wpforms-cc-warning wpforms-error-alert">';
esc_html_e( 'This page is not secure. PayPal Commerce payments should be used for testing purposes only.', 'wpforms-lite' );
echo '</div>';
}
$connection = Connection::get();
if ( ! $connection ) {
echo '<div class="wpforms-cc-warning wpforms-error-alert">';
esc_html_e( 'PayPal Commerce payments are disabled. Please set up a connection with PayPal in your form’s settings.', 'wpforms-lite' );
echo '</div>';
return;
}
if ( ! $connection->is_usable() ) {
echo '<div class="wpforms-cc-warning wpforms-error-alert">';
esc_html_e( 'PayPal Commerce payments are disabled because your connection is not set up correctly. Please ask your site administrator to check the connection settings.', 'wpforms-lite' );
echo '</div>';
return;
}
if ( ! Helpers::is_paypal_commerce_enabled( $form_data ) ) {
echo '<div class="wpforms-cc-warning wpforms-error-alert">';
esc_html_e( 'PayPal Commerce payments are not enabled in the form settings.', 'wpforms-lite' );
echo '</div>';
return;
}
if ( ! isset( $field['credit_card'] ) && ! isset( $field['paypal_checkout'] ) && ! isset( $field['fastlane'] ) ) {
echo '<div class="wpforms-cc-warning wpforms-error-alert">';
esc_html_e( 'PayPal Commerce payments are disabled. Please enable at least one payment method in the form settings.', 'wpforms-lite' );
echo '</div>';
return;
}
if ( ! Helpers::is_subscriptions_configured( $form_data ) ) {
echo '<div class="wpforms-cc-warning wpforms-error-alert">';
esc_html_e( 'PayPal Commerce payments are disabled because details are missing from one of the recurring plans. Please ask your site administrator to check the form settings.', 'wpforms-lite' );
echo '</div>';
return;
}
echo '<input type="hidden" name="wpforms[fields][' . esc_attr( $field['id'] ) . '][orderID]" class="wpforms-paypal-commerce-order-id" />';
echo '<input type="hidden" name="wpforms[fields][' . esc_attr( $field['id'] ) . '][subscriptionID]" class="wpforms-paypal-commerce-subscription-id" />';
echo '<input type="hidden" name="wpforms[fields][' . esc_attr( $field['id'] ) . '][subscriptionProcessorID]" class="wpforms-paypal-commerce-subscription-processor-id" />';
echo '<input type="hidden" name="wpforms[fields][' . esc_attr( $field['id'] ) . '][source]" class="wpforms-paypal-commerce-source" />';
echo '<input type="hidden" name="wpforms[fields][' . esc_attr( $field['id'] ) . '][fastlane_token]" class="wpforms-paypal-commerce-fastlane-token" />';
$this->field_display_default_payment( $field );
$this->field_display_credit_card( $field, $form_data );
$this->field_display_fastlane( $field, $form_data );
}
/**
* Field display default payment on the form front-end.
*
* @since 1.10.0
*
* @param array $field Field data and settings.
*/
private function field_display_default_payment( array $field ): void {
// Collect available payment types dynamically.
$available_methods = [];
if ( ! empty( $field['paypal_checkout'] ) ) {
$available_methods['checkout'] = esc_html__( 'PayPal Checkout', 'wpforms-lite' );
}
if ( ! empty( $field['credit_card'] ) ) {
$available_methods['credit_card'] = esc_html__( 'Credit Card', 'wpforms-lite' );
}
if ( ! empty( $field['fastlane'] ) ) {
$available_methods['fastlane'] = esc_html__( 'Fastlane', 'wpforms-lite' );
}
// Render selector only when 2 or more methods are available.
if ( count( $available_methods ) < 2 ) {
return;
}
$default_method = $field['default_method'] ?? '';
echo '<div class="wpforms-field-row wpforms-field-' . sanitize_html_class( $field['size'] ?? 'medium' ) . '">';
echo '<select class="wpforms-paypal-commerce-payment-method">';
foreach ( $available_methods as $value => $label ) {
$selected = selected( $default_method, $value, false );
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo '<option value="' . esc_attr( $value ) . '" ' . $selected . '>' . esc_html( $label ) . '</option>';
}
echo '</select>';
echo '</div>';
}
/**
* Field display default payment on the form front-end.
*
* @since 1.10.0
*
* @param array $field Field data and settings.
* @param array $form_data Form data and settings.
*/
private function field_display_fastlane( $field, $form_data ) {
if ( ! isset( $field['fastlane'] ) ) {
return;
}
$hide_class = ( ( (int) ! empty( $field['credit_card'] ) + (int) ! empty( $field['paypal_checkout'] ) + (int) ! empty( $field['fastlane'] ) ) > 1 && ( $field['default_method'] ?? '' ) !== 'fastlane' ) ? 'wpforms-hidden' : '';
$defaults = $this->get_default_labels();
$email_placeholder = ! empty( $field['fastlane_email_placeholder'] ) ? $field['fastlane_email_placeholder'] : $defaults['fastlane_email_placeholder'];
$continue_label = ! empty( $field['fastlane_continue_label'] ) ? $field['fastlane_continue_label'] : $defaults['fastlane_continue_label'];
?>
<div class="wpforms-paypal-commerce-fastlane-fields <?php echo sanitize_html_class( $hide_class ); ?>">
<div class="wpforms-field-row wpforms-field-<?php echo sanitize_html_class( $field['size'] ); ?>">
<div class="wpforms-paypal-commerce-fastlane-container">
<div class="wpforms-paypal-commerce-fastlane-email-container">
<input <?php echo ( $field['required'] ?? false ) ? 'required' : ''; ?> class="wpforms-paypal-commerce-fastlane-email-input" maxlength="255" name="email" type="email" placeholder="<?php echo esc_attr( $email_placeholder ); ?>" autocomplete="email" />
<div class="wpforms-paypal-commerce-fastlane-watermark-container">
<img src="<?php echo esc_url( WPFORMS_PLUGIN_URL . 'assets/images/integrations/paypal-commerce/fastlane.svg' ); ?>" alt="<?php echo esc_attr__( 'Fastlane', 'wpforms-lite' ); ?>" />
</div>
</div>
<div class="wpforms-paypal-commerce-fastlane-continue-container">
<button class="wpforms-paypal-commerce-fastlane-email-continue wpforms-page-button" type="button" title="<?php echo esc_attr( $continue_label ); ?>" disabled><?php echo esc_html( $continue_label ); ?></button>
</div>
</div>
</div>
<!-- Payment section -->
<section class="wpforms-paypal-commerce-fastlane-payment" style="display: none">
<div class="wpforms-field-row wpforms-field-<?php echo sanitize_html_class( $field['size'] ); ?>">
<div class="wpforms-paypal-commerce-fastlane-payment-component"></div>
</div>
</section>
</div>
<?php
}
/**
* Field display default payment on the form front-end.
*
* @since 1.10.0
*
* @param array $field Field data and settings.
* @param array $form_data Form data and settings.
*
* @noinspection HtmlUnknownAttribute
*/
private function field_display_credit_card( array $field, array $form_data ): void { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh
if ( ! isset( $field['credit_card'] ) ) {
return;
}
$hide_class = ( ( (int) ! empty( $field['credit_card'] ) + (int) ! empty( $field['paypal_checkout'] ) + (int) ! empty( $field['fastlane'] ) ) > 1 && ( $field['default_method'] ?? '' ) !== 'credit_card' ) ? 'wpforms-hidden' : '';
// Define data.
$number = ! empty( $field['properties']['inputs']['number'] ) ? $field['properties']['inputs']['number'] : [];
$date = ! empty( $field['properties']['inputs']['date'] ) ? $field['properties']['inputs']['date'] : [];
$code = ! empty( $field['properties']['inputs']['code'] ) ? $field['properties']['inputs']['code'] : [];
$name = ! empty( $field['properties']['inputs']['name'] ) ? $field['properties']['inputs']['name'] : [];
echo '<div class="wpforms-paypal-commerce-card-fields ' . sanitize_html_class( $hide_class ) . '">';
echo '<div class="wpforms-field-row wpforms-field-' . sanitize_html_class( $field['size'] ) . '">';
echo '<div class="wpforms-paypal-commerce-supported-cards">';
echo isset( $field['amex'] ) ? '<div class="wpforms-paypal-commerce-amex-icon"></div>' : '';
echo isset( $field['discover'] ) ? '<div class="wpforms-paypal-commerce-discover-icon"></div>' : '';
echo isset( $field['maestro'] ) ? '<div class="wpforms-paypal-commerce-maestro-icon"></div>' : '';
echo isset( $field['mastercard'] ) ? '<div class="wpforms-paypal-commerce-mastercard-icon"></div>' : '';
echo isset( $field['visa'] ) ? '<div class="wpforms-paypal-commerce-visa-icon"></div>' : '';
echo '</div>';
echo '</div>';
// Row wrapper.
echo '<div class="wpforms-field-row wpforms-field-' . sanitize_html_class( $field['size'] ) . '">';
echo '<div ' . wpforms_html_attributes( false, $number['block'] ) . '>';
$this->field_display_sublabel( 'number', 'before', $field );
printf(
'<div %s data-required="%s"></div>',
wpforms_html_attributes( $number['id'], $number['class'], $number['data'], $number['attr'] ),
esc_attr( $number['required'] )
);
// Hidden input is needed for validation.
printf( '<input type="text" class="wpforms-paypal-commerce-credit-card-hidden-input" name="wpforms[paypal-commerce-credit-card-hidden-input-%1$d]" id="wpforms-paypal-commerce-credit-card-hidden-input-%1$d-number" disabled style="display: none;">', (int) $form_data['id'] );
$this->field_display_sublabel( 'number', 'after', $field );
$this->field_display_error( 'number', $field );
echo '</div>';
echo '</div>';
// Row wrapper.
echo '<div class="wpforms-field-row wpforms-field-row-responsive wpforms-field-' . sanitize_html_class( $field['size'] ) . '">';
echo '<div class="wpforms-field-row-block wpforms-one-half wpforms-first ' . wpforms_sanitize_classes( $date['block'], true ) . '">';
$this->field_display_sublabel( 'date', 'before', $field );
printf(
'<div %s data-required="%s"></div>',
wpforms_html_attributes( $date['id'], $date['class'], $date['data'], $date['attr'] ),
esc_attr( $date['required'] )
);
// Hidden input is needed for validation.
printf( '<input type="text" class="wpforms-paypal-commerce-credit-card-hidden-input" name="wpforms[paypal-commerce-credit-card-hidden-input-%1$d]" id="wpforms-paypal-commerce-credit-card-hidden-input-%1$d-date" disabled style="display: none;">', (int) $form_data['id'] );
$this->field_display_sublabel( 'date', 'after', $field );
$this->field_display_error( 'date', $field );
echo '</div>';
echo '<div class="wpforms-field-row-block wpforms-one-half ' . wpforms_sanitize_classes( $code['block'], true ) . '">';
$this->field_display_sublabel( 'code', 'before', $field );
printf(
'<div %s data-required="%s"></div>',
wpforms_html_attributes( $code['id'], $code['class'], $code['data'], $code['attr'] ),
esc_attr( $code['required'] )
);
// Hidden input is needed for validation.
printf( '<input type="text" class="wpforms-paypal-commerce-credit-card-hidden-input" name="wpforms[paypal-commerce-credit-card-hidden-input-%1$d]" id="wpforms-paypal-commerce-credit-card-hidden-input-%1$d-code" disabled style="display: none;">', (int) $form_data['id'] );
$this->field_display_sublabel( 'code', 'after', $field );
$this->field_display_error( 'code', $field );
echo '</div>';
echo '</div>';
if ( ! isset( $field['card_holder_enable'] ) ) {
echo '</div>';
return;
}
// Row wrapper.
echo '<div class="wpforms-field-row wpforms-field-' . sanitize_html_class( $field['size'] ) . '">';
// Name.
echo '<div ' . wpforms_html_attributes( false, $name['block'] ) . '>';
$this->field_display_sublabel( 'name', 'before', $field );
printf(
'<input type="text" %s %s>',
wpforms_html_attributes( $name['id'], $name['class'], $name['data'], $name['attr'] ),
esc_attr( $name['required'] )
);
$this->field_display_sublabel( 'name', 'after', $field );
$this->field_display_error( 'name', $field );
echo '</div>';
echo '</div>';
echo '</div>';
}
/**
* Currently, validation happens on the front end. We do not do
* generic server-side validation because we do not allow the card
* details to POST to the server.
*
* @since 1.10.0
*
* @param int $field_id Field ID.
* @param array $field_submit Submitted field value.
* @param array $form_data Form data and settings.
*/
public function validate( $field_id, $field_submit, $form_data ) {}
/**
* Format field.
*
* @since 1.10.0
*
* @param int $field_id Field ID.
* @param array $field_submit Submitted field value.
* @param array $form_data Form data and settings.
*/
public function format( $field_id, $field_submit, $form_data ): void {
// Define data.
$field_name = ! empty( $form_data['fields'][ $field_id ]['label'] ) ? $form_data['fields'][ $field_id ]['label'] : '';
$card_name = ! empty( $field_submit['cardname'] ) ? $field_submit['cardname'] : '';
// Set final field details.
wpforms()->obj( 'process' )->fields[ $field_id ] = [
'name' => sanitize_text_field( $field_name ),
'cardname' => sanitize_text_field( $card_name ),
'value' => '',
'id' => absint( $field_id ),
'type' => $this->type,
];
}
/**
* Modify for attribute value for sublabels to be the same as its IDs.
*
* @since 1.10.0
*
* @param string $value For attribute value.
* @param string $key Input key.
* @param array $field Field data and settings.
*
* @return string
*
* @noinspection PhpMissingParamTypeInspection
*/
public function modify_sublabel_for( $value, string $key, array $field ): string {
$value = (string) $value;
if ( $field['type'] !== $this->type ) {
return $value;
}
if ( in_array( $key, [ 'date', 'code', 'number' ], true ) ) {
return sprintf( 'wpforms-paypal-commerce-credit-card-hidden-input-%1$d-%2$s', $this->form_data['id'], $key );
}
return $value;
}
}