Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for multiple Default Forms (Site Wide) #754

Merged
merged 5 commits into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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