namespace WPForms\Integrations\Square\Fields;
use WPForms\Integrations\Square\Connection;
use WPForms\Integrations\Square\Helpers;
* Square credit card field.
class Square extends WPForms_Field {
* Primary class constructor.
// Define field type information.
$this->name = esc_html__( 'Square', 'wpforms-lite' );
$this->keywords = esc_html__( 'store, ecommerce, credit card, pay, payment, debit card', 'wpforms-lite' );
$this->icon = 'fa-credit-card';
$this->group = 'payment';
private function hooks() {
add_filter( 'wpforms_field_properties_square', [ $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 );
'wpforms_field_preview_display_duplicate_button',
[ $this, 'field_display_duplicate_button' ],
'wpforms_pro_fields_entry_preview_is_field_support_preview_square_field',
[ $this, 'entry_preview_availability' ],
add_filter( 'wpforms_field_display_sublabel_skip_for', [ $this, 'skip_sublabel_for_attribute' ], 10, 3 );
* Define additional field properties.
* @param array $properties Field properties.
* @param array $field Field settings.
* @param array $form_data Form data and settings.
public function field_properties( $properties, array $field, array $form_data ): array {
$properties = (array) $properties;
unset( $properties['label']['attr']['for'] );
$form_id = absint( $form_data['id'] );
$field_id = absint( $field['id'] );
'wpforms-field-square-number',
'wpforms-field-square-cardnumber',
'id' => "wpforms-{$form_id}-field_{$field_id}",
'required' => ! empty( $field['required'] ) ? 'required' : '',
'hidden' => ! empty( $field['sublabel_hide'] ),
'value' => esc_html__( 'Card', 'wpforms-lite' ),
'name' => "wpforms[fields][{$field_id}][cardname]",
'placeholder' => ! empty( $field['cardname_placeholder'] ) ? $field['cardname_placeholder'] : '',
'wpforms-field-square-name',
'wpforms-field-square-cardname',
'id' => "wpforms-{$form_id}-field_{$field_id}-cardname",
'required' => ! empty( $field['required'] ) ? 'required' : '',
'hidden' => ! empty( $field['sublabel_hide'] ),
'value' => esc_html__( 'Name on Card', 'wpforms-lite' ),
$properties = array_merge_recursive( $properties, $props );
// If this field is required, we need to make some adjustments.
if ( ! empty( $field['required'] ) ) {
// Add required class if needed (for multipage validation).
$properties['inputs']['number']['class'][] = 'wpforms-field-required';
$properties['inputs']['name']['class'][] = 'wpforms-field-required';
* Default to the required.
* @param bool $required Required status, true is required.
* @param array $field Field settings.
public function default_required( $required, array $field ): bool {
return $this->type === $field['type'] ? true : (bool) $required;
* Define additional "Add Field" button attributes.
* @param array $atts Add Field button attributes.
* @param array $field Field settings.
* @param array $form_data Form data and settings.
public function field_button_atts( $atts, array $field, array $form_data ): array {
if ( $field['type'] !== $this->type ) {
if ( Helpers::has_square_field( $form_data ) ) {
$atts['atts']['disabled'] = 'true';
$atts['class'][] = 'wpforms-add-fields-button-disabled';
if ( ! Connection::get() ) {
$atts['class'][] = 'warning-modal';
$atts['class'][] = 'square-connection-required';
* Disallow field preview "Duplicate" button.
* @param bool $display Display switch.
* @param array $field Field settings.
public function field_display_duplicate_button( $display, array $field ): bool {
return $field['type'] === $this->type ? false : (bool) $display;
* The field value availability for the Entry Preview field.
* @param bool $is_supported The field availability.
* @param string|array $value The submitted Credit Card detail.
* @param array $field Field data.
* @param array $form_data Form data.
* @noinspection PhpUnusedParameterInspection
public function entry_preview_availability( $is_supported, $value, array $field, array $form_data ): bool {
return ! empty( $value );
* Disallow dynamic population.
* @param array $properties Field properties.
* @param array $field Current field specific data.
public function is_dynamic_population_allowed( $properties, $field ): bool {
* Disallow fallback population.
* @param array $properties Field properties.
* @param array $field Current field specific data.
public function is_fallback_population_allowed( $properties, $field ): bool {
* Field options panel inside the builder.
* @param array $field Field settings.
public function field_options( $field ) {
$this->field_option( 'basic-options', $field, $args );
$this->field_option( 'label', $field );
$this->field_option( 'description', $field );
$this->field_option( 'required', $field );
$this->field_option( 'basic-options', $field, $args );
* Advanced field options.
$this->field_option( 'advanced-options', $field, $args );
$this->field_option( 'size', $field );
$cardname_placeholder = ! empty( $field['cardname_placeholder'] ) ? esc_attr( $field['cardname_placeholder'] ) : '';
$cardname_field = sprintf( '<div class="placeholder"><input type="text" class="placeholder-update" id="wpforms-field-option-%1$d-cardname_placeholder" name="fields[%1$d][cardname_placeholder]" value="%2$s" data-field-id="%1$d" data-subfield="square-cardname"></div>', absint( $field['id'] ), esc_html( $cardname_placeholder ) );
'<div class="wpforms-clear wpforms-field-option-row wpforms-field-option-row-cardname" id="wpforms-field-option-row-%1$d-cardname" data-subfield="cardname" data-field-id="%1$d">',
'slug' => 'cardname_placeholder',
'value' => esc_html__( 'Name on Card Placeholder Text', 'wpforms-lite' ),
echo $cardname_field; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
$this->field_option( 'css', $field );
$this->field_option( 'label_hide', $field );
$this->field_option( 'sublabel_hide', $field );
$this->field_option( 'advanced-options', $field, $args );
* Field preview inside the builder.
* @param array $field Field settings.
public function field_preview( $field ) {
$this->field_preview_option( 'label', $field );
$this->field_preview_placeholder( $field );
$this->field_preview_option( 'description', $field );
* Field display on the form front-end.
* @param array $field Field data and settings.
* @param array $deprecated Deprecated field attributes. Use field properties.
* @param array $form_data Form data and settings.
* @noinspection HtmlUnknownAttribute
public function field_display( $field, $deprecated, $form_data ) {
if ( wpforms_is_editor_page() ) {
$this->field_preview_placeholder( $field );
$number = ! empty( $field['properties']['inputs']['number'] ) ? $field['properties']['inputs']['number'] : [];
$name = ! empty( $field['properties']['inputs']['name'] ) ? $field['properties']['inputs']['name'] : [];
// Display warning for non SSL pages.
echo '<div class="wpforms-cc-warning wpforms-error-alert">';
esc_html_e( 'This page is insecure. Credit Card field should be used for testing purposes only.', 'wpforms-lite' );
$connection = Connection::get();
echo '<div class="wpforms-cc-warning wpforms-error-alert">';
esc_html_e( 'Credit Card field is disabled, Square account connection is missing.', 'wpforms-lite' );
if ( ! $connection->is_usable() ) {
echo '<div class="wpforms-cc-warning wpforms-error-alert">';
esc_html_e( 'Credit Card field is disabled, Square account connection is invalid. Please, contact to the site administrator.', 'wpforms-lite' );
if ( ! Helpers::is_payments_enabled( $form_data ) ) {
echo '<div class="wpforms-cc-warning wpforms-error-alert">';
esc_html_e( 'Credit Card field is disabled, Square payments are not enabled in the form settings.', 'wpforms-lite' );
if ( $connection->is_expired() && wpforms_current_user_can() ) {
echo '<div class="wpforms-cc-warning wpforms-error-alert">';
esc_html_e( 'Heads up! Square account connection is expired. Tokens must be refreshed.', 'wpforms-lite' );
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 );
'<div %s data-required="%s"><!-- Square credit card will be inserted here. --></div>',
wpforms_html_attributes( $number['id'], $number['class'], $number['data'], $number['attr'] ),
esc_attr( $number['required'] )
// Hidden input is needed for validation on the frontend and as a substitute in Block Editor previews.
class="wpforms-square-credit-card-hidden-input"
name="wpforms[square-credit-card-hidden-input-%1$d]"
id="wpforms-square-credit-card-hidden-input-%1$d"
wpforms_is_editor_page() ? '' : 'style="display: none;" disabled'
$this->field_display_sublabel( 'number', 'after', $field );
$this->field_display_error( 'number', $field );
echo '<div class="wpforms-field-row wpforms-field-' . sanitize_html_class( $field['size'] ) . '">';
echo '<div ' . wpforms_html_attributes( false, $name['block'] ) . '>';
$this->field_display_sublabel( 'name', 'before', $field );
'<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 );
* 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.
* @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 ) {}
* @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 ) {
$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 ),
'id' => absint( $field_id ),
* Card field placeholder.