Skip to content

Commit

Permalink
Merge pull request #754 from Kit/support-multiple-site-wide-forms
Browse files Browse the repository at this point in the history
Add support for multiple Default Forms (Site Wide)
  • Loading branch information
n7studios authored Dec 12, 2024
2 parents 84461aa + 3aeec1c commit dd04ea3
Show file tree
Hide file tree
Showing 9 changed files with 370 additions and 80 deletions.
8 changes: 3 additions & 5 deletions admin/section/class-convertkit-settings-general.php
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ public function register_fields() {

add_settings_field(
'non_inline_form',
__( 'Default Form (Site Wide)', 'convertkit' ),
__( 'Default Forms (Site Wide)', 'convertkit' ),
array( $this, 'non_inline_form_callback' ),
$this->settings_key,
$this->name,
Expand Down Expand Up @@ -657,7 +657,7 @@ public function non_inline_form_callback( $args ) {
$preview_url = WP_ConvertKit()->get_class( 'preview_output' )->get_preview_form_home_url();
$description = sprintf(
'%s %s %s',
esc_html__( 'Select a non-inline modal, slide in or sticky bar form to automatically display site wide. Ignored if a non-inline form is specified in Default Form settings above, individual Post / Page settings, or any block / shortcode.', 'convertkit' ),
esc_html__( 'Select one or more non-inline modal, slide in or sticky bar forms to automatically display site wide. Ignored if a non-inline form is specified in Default Form settings above, individual Post / Page settings, or any block / shortcode.', 'convertkit' ),
'<a href="' . esc_url( $preview_url ) . '" id="convertkit-preview-non-inline-form" target="_blank">' . esc_html__( 'Click here', 'convertkit' ) . '</a>',
esc_html__( 'to preview how this will display.', 'convertkit' )
);
Expand All @@ -671,9 +671,7 @@ public function non_inline_form_callback( $args ) {
'convertkit-preview-output-link',
),
$this->settings->get_non_inline_form(),
array(
'' => esc_html__( 'None', 'convertkit' ),
),
false,
array(
'data-target' => '#convertkit-preview-non-inline-form',
'data-link' => esc_attr( $preview_url ) . '&convertkit_form_id=',
Expand Down
43 changes: 24 additions & 19 deletions includes/class-convertkit-output.php
Original file line number Diff line number Diff line change
Expand Up @@ -803,8 +803,8 @@ public function get_subscriber_id_from_request() {
}

/**
* Outputs a non-inline form if defined in the Plugin's settings >
* Default Non-Inline Form (Global) setting.
* Outputs a non-inline forms if defined in the Plugin's settings >
* Default Forms (Site Wide) setting.
*
* @since 2.3.3
*/
Expand All @@ -822,28 +822,33 @@ public function output_global_non_inline_form() {

// Get form.
$convertkit_forms = new ConvertKit_Resource_Forms();
$form = $convertkit_forms->get_by_id( (int) $this->settings->get_non_inline_form() );

// Bail if the Form doesn't exist (this shouldn't happen, but you never know).
if ( ! $form ) {
return;
}
// Iterate through forms.
foreach ( $this->settings->get_non_inline_form() as $form_id ) {
// Get Form.
$form = $convertkit_forms->get_by_id( (int) $form_id );

// Add the form to the scripts array so it is included in the output.
add_filter(
'convertkit_output_scripts_footer',
function ( $scripts ) use ( $form ) {
// Bail if the Form doesn't exist (this shouldn't happen, but you never know).
if ( ! $form ) {
continue;
}

$scripts[] = array(
'async' => true,
'data-uid' => $form['uid'],
'src' => $form['embed_js'],
);
// Add the form to the scripts array so it is included in the output.
add_filter(
'convertkit_output_scripts_footer',
function ( $scripts ) use ( $form ) {

return $scripts;
$scripts[] = array(
'async' => true,
'data-uid' => $form['uid'],
'src' => $form['embed_js'],
);

}
);
return $scripts;

}
);
}

}

Expand Down
49 changes: 28 additions & 21 deletions includes/class-convertkit-preview-output.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public function preview_form( $form_id ) {
}

/**
* Adds a non-inline form for display if the request is from a logged in user who has clicked a preview link
* Adds non-inline form(s) for display if the request is from a logged in user who has clicked a preview link
* and is viewing the home page.
*
* @since 2.3.3
Expand All @@ -99,33 +99,40 @@ public function preview_non_inline_form() {
return;
}

// Determine the form to preview.
$preview_form_id = (int) ( isset( $_REQUEST['convertkit_form_id'] ) ? sanitize_text_field( $_REQUEST['convertkit_form_id'] ) : 0 );
// Bail if no form(s) to preview.
if ( ! isset( $_REQUEST['convertkit_form_id'] ) ) {
return;
}

// Get form.
// Determine form ID(s) to preview.
$convertkit_forms = new ConvertKit_Resource_Forms();
$form = $convertkit_forms->get_by_id( $preview_form_id );
$preview_form_ids = explode( ',', sanitize_text_field( $_REQUEST['convertkit_form_id'] ) );

// Bail if the Form doesn't exist (this shouldn't happen, but you never know).
if ( ! $form ) {
return;
}
foreach ( $preview_form_ids as $preview_form_id ) {
// Get form.
$form = $convertkit_forms->get_by_id( (int) $preview_form_id );

// Add the form to the scripts array so it is included in the preview.
add_filter(
'convertkit_output_scripts_footer',
function ( $scripts ) use ( $form ) {
// Bail if the Form doesn't exist (this shouldn't happen, but you never know).
if ( ! $form ) {
continue;
}

$scripts[] = array(
'async' => true,
'data-uid' => $form['uid'],
'src' => $form['embed_js'],
);
// Add the form to the scripts array so it is included in the preview.
add_filter(
'convertkit_output_scripts_footer',
function ( $scripts ) use ( $form ) {

return $scripts;
$scripts[] = array(
'async' => true,
'data-uid' => $form['uid'],
'src' => $form['embed_js'],
);

}
);
return $scripts;

}
);
}

}

Expand Down
105 changes: 94 additions & 11 deletions includes/class-convertkit-resource-forms.php
Original file line number Diff line number Diff line change
Expand Up @@ -154,23 +154,23 @@ public function get_select_field_all( $name, $id, $css_classes, $selected_option
*
* @since 2.3.9
*
* @param string $name Name.
* @param string $id ID.
* @param bool|array $css_classes <select> CSS class(es).
* @param string $selected_option <option> value to mark as selected.
* @param bool|array $prepend_options <option> elements to prepend before resources.
* @param bool|array $attributes <select> attributes.
* @param bool|string|array $description Description.
* @return string HTML Select Field
* @param string $name Name.
* @param string $id ID.
* @param bool|array $css_classes <select> CSS class(es).
* @param array $selected_options <option> values to mark as selected.
* @param bool|array $prepend_options <option> elements to prepend before resources.
* @param bool|array $attributes <select> attributes.
* @param bool|string|array $description Description.
* @return string HTML Select Field
*/
public function get_select_field_non_inline( $name, $id, $css_classes, $selected_option, $prepend_options = false, $attributes = false, $description = false ) {
public function get_select_field_non_inline( $name, $id, $css_classes, $selected_options, $prepend_options = false, $attributes = false, $description = false ) {

return $this->get_select_field(
return $this->get_multi_select_field(
$this->get_non_inline(),
$name,
$id,
$css_classes,
$selected_option,
$selected_options,
$prepend_options,
$attributes,
$description
Expand Down Expand Up @@ -260,6 +260,89 @@ private function get_select_field( $forms, $name, $id, $css_classes, $selected_o

}

/**
* Returns a <select> field populated with the resources, based on the given parameters,
* that supports multiple selection.
*
* @since 2.6.9
*
* @param array $forms Forms.
* @param string $name Name.
* @param string $id ID.
* @param bool|array $css_classes <select> CSS class(es).
* @param array $selected_options <option> values to mark as selected.
* @param bool|array $prepend_options <option> elements to prepend before resources.
* @param bool|array $attributes <select> attributes.
* @param bool|string|array $description Description.
* @return string HTML Select Field
*/
private function get_multi_select_field( $forms, $name, $id, $css_classes, $selected_options = array(), $prepend_options = false, $attributes = false, $description = false ) {

$html = sprintf(
'<select name="%s[]" id="%s" class="%s" multiple',
esc_attr( $name ),
esc_attr( $id ),
esc_attr( ( is_array( $css_classes ) ? implode( ' ', $css_classes ) : '' ) )
);

// Append any attributes.
if ( $attributes ) {
foreach ( $attributes as $key => $value ) {
$html .= sprintf(
' %s="%s"',
esc_attr( $key ),
esc_attr( $value )
);
}
}

// Close select tag.
$html .= '>';

// If any prepended options exist, add them now.
if ( $prepend_options ) {
foreach ( $prepend_options as $value => $label ) {
$html .= sprintf(
'<option value="%s" data-preserve-on-refresh="1"%s>%s</option>',
esc_attr( $value ),
( in_array( $value, $selected_options, true ) ? ' selected' : '' ),
esc_attr( $label )
);
}
}

// Iterate through resources, if they exist, building <option> elements.
if ( $forms ) {
foreach ( $forms as $form ) {
// Legacy forms don't include a `format` key, so define them as inline.
$html .= sprintf(
'<option value="%s"%s>%s [%s]</option>',
esc_attr( $form['id'] ),
( in_array( $form['id'], $selected_options, true ) ? ' selected' : '' ),
esc_attr( $form['name'] ),
( ! empty( $form['format'] ) ? esc_attr( $form['format'] ) : 'inline' )
);
}
}

// Close select.
$html .= '</select>';

// If no description is provided, return the select field now.
if ( ! $description ) {
return $html;
}

// Append description before returning field.
if ( ! is_array( $description ) ) {
return $html . '<p class="description">' . $description . '</p>';
}

// Return description lines in a paragraph, using breaklines for each description entry in the array.
return $html . '<p class="description">' . implode( '<br />', $description ) . '</p>';

}

/**
* Returns the HTML/JS markup for the given Form ID.
*
Expand Down
27 changes: 21 additions & 6 deletions includes/class-convertkit-settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -353,16 +353,22 @@ public function get_default_form_position_element_index( $post_type ) {
*
* @since 2.3.3
*
* @return string|int Non-inline Form (blank string|form id)
* @return array
*/
public function get_non_inline_form() {

// Return blank string if no inline form is specified.
// Return blank array if no inline form is specified.
if ( ! $this->has_non_inline_form() ) {
return '';
return array();
}

// 2.6.8 and earlier stored a single Form ID in a string.
if ( is_string( $this->settings['non_inline_form'] ) ) {
return array( (int) $this->settings['non_inline_form'] );
}

return $this->settings['non_inline_form'];
// Cast values to integers and return.
return array_map( 'intval', $this->settings['non_inline_form'] );

}

Expand All @@ -375,7 +381,16 @@ public function get_non_inline_form() {
*/
public function has_non_inline_form() {

return ( ! empty( $this->settings['non_inline_form'] ) ? true : false );
// 2.6.8 and earlier stored a single Form ID in a string.
if ( is_string( $this->settings['non_inline_form'] ) ) {
if ( ! empty( $this->settings['non_inline_form'] ) ) {
return true;
}

return false;
}

return ( count( $this->settings['non_inline_form'] ) > 0 ? true : false );

}

Expand Down Expand Up @@ -439,7 +454,7 @@ public function get_defaults() {
'api_secret' => '', // string.

// Settings.
'non_inline_form' => '', // string.
'non_inline_form' => array(), // array.
'debug' => '', // blank|on.
'no_scripts' => '', // blank|on.
'no_css' => '', // blank|on.
Expand Down
2 changes: 1 addition & 1 deletion tests/_support/Helper/Acceptance/ConvertKitPlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public function setupConvertKitPlugin($I, $options = false)
'post_form' => $_ENV['CONVERTKIT_API_FORM_ID'],
'page_form' => $_ENV['CONVERTKIT_API_FORM_ID'],
'product_form' => $_ENV['CONVERTKIT_API_FORM_ID'],
'non_inline_form' => '',
'non_inline_form' => array(),
];

// If supplied options are an array, merge them with the defaults.
Expand Down
19 changes: 19 additions & 0 deletions tests/_support/Helper/Acceptance/Select2.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,23 @@ public function fillSelect2Field($I, $container, $value, $ariaAttributeName = 'a
$I->waitForElementVisible('ul#select2-' . $fieldName . '-results li.select2-results__option--highlighted');
$I->pressKey('.select2-search__field[' . $ariaAttributeName . '="select2-' . $fieldName . '-results"]', \Facebook\WebDriver\WebDriverKeys::ENTER);
}

/**
* Helper method to enter text into a jQuery Select2 multiple selection field, selecting the option that appears.
*
* @since 2.6.9
*
* @param AcceptanceTester $I Tester.
* @param string $container Field CSS Class / ID.
* @param string $value Field Value.
* @param string $ariaAttributeName Aria Attribute Name (aria-controls|aria-owns).
*/
public function fillSelect2MultipleField($I, $container, $value, $ariaAttributeName = 'aria-describedby')
{
$fieldID = $I->grabAttributeFrom($container, 'id');
$fieldName = str_replace('-container', '', str_replace('select2-', '', $fieldID));
$I->fillField('.select2-search__field[' . $ariaAttributeName . '="select2-' . $fieldName . '-container"]', $value);
$I->waitForElementVisible('ul#select2-' . $fieldName . '-results li.select2-results__option--highlighted');
$I->pressKey('.select2-search__field[' . $ariaAttributeName . '="select2-' . $fieldName . '-container"]', \Facebook\WebDriver\WebDriverKeys::ENTER);
}
}
Loading

0 comments on commit dd04ea3

Please sign in to comment.