Commit realizado el 12:13:52 08-04-2024

This commit is contained in:
Pagina Web Monito
2024-04-08 12:13:55 -04:00
commit 0c33094de9
7815 changed files with 1365694 additions and 0 deletions

View File

@@ -0,0 +1,712 @@
<?php
/**
* Global admin related items and functionality.
*
* @since 1.3.9
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
use WPForms\Admin\Notice;
/**
* Load styles for all WPForms-related admin screens.
*
* @since 1.3.9
*/
function wpforms_admin_styles() {
if ( ! wpforms_is_admin_page() ) {
return;
}
$min = wpforms_get_min_suffix();
// jQuery confirm.
wp_enqueue_style(
'jquery-confirm',
WPFORMS_PLUGIN_URL . 'assets/lib/jquery.confirm/jquery-confirm.min.css',
[],
'3.3.4'
);
// Minicolors (color picker).
wp_enqueue_style(
'minicolors',
WPFORMS_PLUGIN_URL . 'assets/lib/jquery.minicolors/jquery.minicolors.min.css',
[],
'2.2.6'
);
// FontAwesome.
wp_enqueue_style(
'wpforms-font-awesome',
WPFORMS_PLUGIN_URL . 'assets/lib/font-awesome/font-awesome.min.css',
null,
'4.7.0'
);
// Main admin styles.
wp_enqueue_style(
'wpforms-admin',
WPFORMS_PLUGIN_URL . "assets/css/admin{$min}.css",
[],
WPFORMS_VERSION
);
// Remove TinyMCE editor styles from third-party themes and plugins.
remove_editor_styles();
// WordPress 5.7 color set.
if ( version_compare( get_bloginfo( 'version' ), '5.7', '>=' ) ) {
wp_enqueue_style(
'wpforms-admin-wp5.7-color',
WPFORMS_PLUGIN_URL . "assets/css/admin-wp5.7-colors{$min}.css",
[ 'wpforms-admin' ],
WPFORMS_VERSION
);
}
}
add_action( 'admin_enqueue_scripts', 'wpforms_admin_styles', 5 );
/**
* Load scripts for all WPForms-related admin screens.
*
* @since 1.3.9
*/
function wpforms_admin_scripts() {
if ( ! wpforms_is_admin_page() ) {
return;
}
$min = wpforms_get_min_suffix();
wp_enqueue_media();
// jQuery confirm.
wp_enqueue_script(
'jquery-confirm',
WPFORMS_PLUGIN_URL . 'assets/lib/jquery.confirm/jquery-confirm.min.js',
[ 'jquery' ],
'3.3.4',
false
);
// Minicolors (color picker).
wp_enqueue_script(
'minicolors',
WPFORMS_PLUGIN_URL . 'assets/lib/jquery.minicolors/jquery.minicolors.min.js',
[ 'jquery' ],
'2.2.6',
false
);
// Choices.js.
wp_enqueue_script(
'choicesjs',
WPFORMS_PLUGIN_URL . 'assets/lib/choices.min.js',
[],
'9.0.1',
false
);
// jQuery Conditionals.
wp_enqueue_script(
'jquery-conditionals',
WPFORMS_PLUGIN_URL . 'assets/lib/jquery.conditionals.min.js',
[ 'jquery' ],
'1.0.1',
false
);
wp_enqueue_script(
'wpforms-generic-utils',
WPFORMS_PLUGIN_URL . "assets/js/utils{$min}.js",
[ 'jquery' ],
WPFORMS_VERSION,
true
);
// Load admin utils JS.
wp_enqueue_script(
'wpforms-admin-utils',
WPFORMS_PLUGIN_URL . "assets/js/admin-utils{$min}.js",
[ 'jquery' ],
WPFORMS_VERSION,
true
);
// Main admin script.
wp_enqueue_script(
'wpforms-admin',
WPFORMS_PLUGIN_URL . "assets/js/admin{$min}.js",
[ 'jquery' ],
WPFORMS_VERSION,
false
);
$default_choicesjs_loading_text = esc_html__( 'Loading...', 'wpforms-lite' );
$default_choicesjs_no_results_text = esc_html__( 'No results found', 'wpforms-lite' );
$default_choicesjs_no_choices_text = esc_html__( 'No choices to choose from', 'wpforms-lite' );
$strings = [
'addon_activate' => esc_html__( 'Activate', 'wpforms-lite' ),
'addon_activated' => esc_html__( 'Activated', 'wpforms-lite' ),
'addon_active' => esc_html__( 'Active', 'wpforms-lite' ),
'addon_deactivate' => esc_html__( 'Deactivate', 'wpforms-lite' ),
'addon_inactive' => esc_html__( 'Inactive', 'wpforms-lite' ),
'addon_install' => esc_html__( 'Install Addon', 'wpforms-lite' ),
'addon_error' => sprintf(
wp_kses( /* translators: %1$s - addon download URL, %2$s - link to manual installation guide. */
__( 'Could not install the addon. Please <a href="%1$s" target="_blank" rel="noopener noreferrer">download it from wpforms.com</a> and <a href="%2$s" target="_blank" rel="noopener noreferrer">install it manually</a>.', 'wpforms-lite' ),
[
'a' => [
'href' => true,
'target' => true,
'rel' => true,
],
]
),
'https://wpforms.com/account/licenses/',
'https://wpforms.com/docs/how-to-manually-install-addons-in-wpforms/'
),
'plugin_error' => esc_html__( 'Could not install the plugin automatically. Please download and install it manually.', 'wpforms-lite' ),
'addon_search' => esc_html__( 'Searching Addons', 'wpforms-lite' ),
'ajax_url' => admin_url( 'admin-ajax.php' ),
'cancel' => esc_html__( 'Cancel', 'wpforms-lite' ),
'continue' => esc_html__( 'Continue', 'wpforms-lite' ),
'close' => esc_html__( 'Close', 'wpforms-lite' ),
'close_refresh' => esc_html__( 'Close and Refresh', 'wpforms-lite' ),
'entry_delete_confirm' => esc_html__( 'Are you sure you want to delete this entry and all its information (files, notes, logs, etc.)?', 'wpforms-lite' ),
'entry_delete_all_confirm' => esc_html__( 'Are you sure you want to delete ALL entries and all their information (files, notes, logs, etc.)?', 'wpforms-lite' ),
'entry_delete_n_confirm' => sprintf( /* translators: %s - entry count. */
esc_html__( 'Are you sure you want to delete %s entry(s) and all the information (files, notes, logs, etc.)?', 'wpforms-lite' ),
'{entry_count}'
),
'entry_trash_confirm' => esc_html__( 'Are you sure you want to trash this entry and all its information (files, notes, logs, etc.)?', 'wpforms-lite' ),
'entry_trash_all_confirm' => esc_html__( 'Are you sure you want to trash ALL entries and all their information (files, notes, logs, etc.)?', 'wpforms-lite' ),
'entry_trash_n_confirm' => sprintf( /* translators: %s - entry count. */
esc_html__( 'Are you sure you want to trash %s entry(s) and all the information (files, notes, logs, etc.)?', 'wpforms-lite' ),
'{entry_count}'
),
'entry_empty_fields_hide' => esc_html__( 'Hide Empty Fields', 'wpforms-lite' ),
'entry_empty_fields_show' => esc_html__( 'Show Empty Fields', 'wpforms-lite' ),
'entry_field_columns' => esc_html__( 'Entries Field Columns', 'wpforms-lite' ),
'entry_note_delete_confirm' => esc_html__( 'Are you sure you want to delete this note?', 'wpforms-lite' ),
'entry_unstar' => esc_html__( 'Unstar entry', 'wpforms-lite' ),
'entry_star' => esc_html__( 'Star entry', 'wpforms-lite' ),
'entry_read' => esc_html__( 'Mark entry read', 'wpforms-lite' ),
'entry_unread' => esc_html__( 'Mark entry unread', 'wpforms-lite' ),
'form_delete_confirm' => esc_html__( 'Are you sure you want to delete this form and all its entries?', 'wpforms-lite' ),
'form_delete_n_confirm' => esc_html__( 'Are you sure you want to delete the selected forms and all their entries?', 'wpforms-lite' ),
'form_delete_all_confirm' => esc_html__( 'Are you sure you want to delete ALL the forms in the trash and all their entries?', 'wpforms-lite' ),
'form_duplicate_confirm' => esc_html__( 'Are you sure you want to duplicate this form?', 'wpforms-lite' ),
'heads_up' => esc_html__( 'Heads up!', 'wpforms-lite' ),
'importer_forms_required' => esc_html__( 'Please select at least one form to import.', 'wpforms-lite' ),
'isPro' => wpforms()->is_pro(),
'nonce' => wp_create_nonce( 'wpforms-admin' ),
'almost_done' => esc_html__( 'Almost Done', 'wpforms-lite' ),
'thanks_for_interest' => esc_html__( 'Thanks for your interest in WPForms Pro!', 'wpforms-lite' ),
'oops' => esc_html__( 'Oops!', 'wpforms-lite' ),
'ok' => esc_html__( 'OK', 'wpforms-lite' ),
'plugin_install_activate_btn' => esc_html__( 'Install and Activate', 'wpforms-lite' ),
'plugin_install_activate_confirm' => esc_html__( 'needs to be installed and activated to import its forms. Would you like us to install and activate it for you?', 'wpforms-lite' ),
'plugin_activate_btn' => esc_html__( 'Activate', 'wpforms-lite' ),
'plugin_activate_confirm' => esc_html__( 'needs to be activated to import its forms. Would you like us to activate it for you?', 'wpforms-lite' ),
'provider_delete_confirm' => esc_html__( 'Are you sure you want to disconnect this account?', 'wpforms-lite' ),
'provider_delete_error' => esc_html__( 'Could not disconnect this account.', 'wpforms-lite' ),
'provider_auth_error' => esc_html__( 'Could not authenticate with the provider.', 'wpforms-lite' ),
'connecting' => esc_html__( 'Connecting...', 'wpforms-lite' ),
'save_refresh' => esc_html__( 'Save and Refresh', 'wpforms-lite' ),
'server_error' => esc_html__( 'Unfortunately there was a server connection error.', 'wpforms-lite' ),
'settings_form_style_base' => sprintf(
wp_kses( /* translators: %s - WPForms.com docs page URL. */
__( 'You\'ve selected <strong>Base Styling Only</strong>, which may result in styling issues. <a href="%s" target="_blank" rel="noopener noreferrer">Please check out our tutorial</a> for common issues and recommendations.', 'wpforms-lite' ),
[
'strong' => [],
'a' => [
'href' => [],
'target' => [],
'rel' => [],
],
]
),
esc_url( wpforms_utm_link( 'https://wpforms.com/docs/how-to-choose-an-include-form-styling-setting/', 'settings-license-modal', 'Base Styling Only' ) )
),
'settings_form_style_none' => sprintf(
wp_kses( /* translators: %s - WPForms.com docs page URL. */
__( 'You\'ve selected <strong>No Styling</strong>, which will likely result in significant styling issues and is recommended only for developers. <a href="%s" target="_blank" rel="noopener noreferrer">Please check out our tutorial</a> for more details and recommendations.', 'wpforms-lite' ),
[
'strong' => [],
'a' => [
'href' => [],
'target' => [],
'rel' => [],
],
]
),
esc_url( wpforms_utm_link( 'https://wpforms.com/docs/how-to-choose-an-include-form-styling-setting/', 'settings-license-modal', 'No Styling' ) )
),
'testing' => esc_html__( 'Testing', 'wpforms-lite' ),
'upgrade_completed' => esc_html__( 'Upgrade was successfully completed!', 'wpforms-lite' ),
'upload_image_title' => esc_html__( 'Upload or Choose Your Image', 'wpforms-lite' ),
'upload_image_button' => esc_html__( 'Use Image', 'wpforms-lite' ),
'upgrade_modal' => wpforms_get_upgrade_modal_text(),
'choicesjs_loading' => $default_choicesjs_loading_text,
'choicesjs_no_results' => $default_choicesjs_no_results_text,
'choicesjs_no_choices' => $default_choicesjs_no_choices_text,
'debug' => wpforms_debug(),
'edit_license' => esc_html__( 'To edit the License Key, please first click the Remove Key button. Please note that removing this key will remove access to updates, addons, and support.', 'wpforms-lite' ),
'something_went_wrong' => esc_html__( 'Something went wrong', 'wpforms-lite' ),
'success' => esc_html__( 'Success', 'wpforms-lite' ),
'loading' => esc_html__( 'Loading...', 'wpforms-lite' ),
'use_simple_contact_form' => esc_html__( 'Use Simple Contact Form Template', 'wpforms-lite' ),
'error_select_template' => esc_html__( 'Please close the form builder and try again. If the error persists, contact our support team.', 'wpforms-lite' ),
'try_again' => sprintf(
wp_kses( /* translators: %s - link to WPForms.com docs page. */
__( 'Something went wrong. Please try again, and if the problem persists, <a href="%1$s" target="_blank" rel="noopener noreferrer">contact our support team</a>.', 'wpforms-lite' ),
[
'a' => [
'href' => [],
'target' => [],
'rel' => [],
],
]
),
esc_url( wpforms_utm_link( 'https://wpforms.com/contact/', 'error-modal', 'contact our support team' ) )
),
];
/**
* Allow theme/plugin developers to adjust main strings on backend/admin part.
*
* @since 1.3.9
*
* @param array $strings Main admin localized strings.
*/
$strings = (array) apply_filters( 'wpforms_admin_strings', $strings );
/**
* Allow theme/plugin developers to adjust Choices.js settings on backend/admin part.
*
* @see https://github.com/Choices-js/Choices#setup For configuration options.
*
* @since 1.7.3
*
* @param array $choicesjs_config Choicesjs configuration.
*/
$choicesjs_config = (array) apply_filters(
'wpforms_admin_scripts_choicesjs_config',
[
'searchEnabled' => false,
// Forces the search to look for exact matches anywhere in the string.
'fuseOptions' => [
'threshold' => 0.1,
'distance' => 1000,
],
'loadingText' => ! empty( $strings['choicesjs_loading'] ) ? $strings['choicesjs_loading'] : $default_choicesjs_loading_text,
'noResultsText' => ! empty( $strings['choicesjs_no_results'] ) ? $strings['choicesjs_no_results'] : $default_choicesjs_no_results_text,
'noChoicesText' => ! empty( $strings['choicesjs_no_choices'] ) ? $strings['choicesjs_no_choices'] : $default_choicesjs_no_choices_text,
]
);
wp_localize_script(
'wpforms-admin',
'wpforms_admin_choicesjs_config',
$choicesjs_config
);
wp_localize_script(
'wpforms-admin',
'wpforms_admin',
$strings
);
}
add_action( 'admin_enqueue_scripts', 'wpforms_admin_scripts' );
/**
* Add body class to WPForms admin pages for easy reference.
*
* @since 1.3.9
*
* @param string $classes CSS classes, space separated.
*
* @return string
*/
function wpforms_admin_body_class( $classes ) {
if ( ! wpforms_is_admin_page() ) {
return $classes;
}
return "$classes wpforms-admin-page";
}
add_filter( 'admin_body_class', 'wpforms_admin_body_class', 10, 1 );
/**
* Output the WPForms admin header.
*
* @since 1.3.9
*/
function wpforms_admin_header() {
// Bail if we're not on a WPForms screen or page (also exclude form builder).
if ( ! wpforms_is_admin_page() ) {
return;
}
/**
* Prevent admin header outputting if needed.
*
* @since 1.5.7
*
* @param bool $is_admin_header_visible True if admin page header should be outputted.
*/
if ( ! apply_filters( 'wpforms_admin_header', true ) ) {
return;
}
// Omit header from Welcome activation screen.
// phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
if ( sanitize_key( $_REQUEST['page'] ) === 'wpforms-getting-started' ) {
return;
}
/**
* Fire before the admin header is outputted.
*
* @since 1.5.7
*/
do_action( 'wpforms_admin_header_before' );
?>
<div id="wpforms-header-temp"></div>
<div id="wpforms-header" class="wpforms-header">
<img class="wpforms-header-logo" src="<?php echo esc_url( WPFORMS_PLUGIN_URL . 'assets/images/logo.png' ); ?>" alt="WPForms Logo">
</div>
<?php
/**
* Fire after the admin header is outputted.
*
* @since 1.5.7
*/
do_action( 'wpforms_admin_header_after' );
}
add_action( 'in_admin_header', 'wpforms_admin_header', 100 );
/**
* Remove non-WPForms notices from WPForms pages.
*
* @since 1.3.9
* @since 1.6.9 Added callback for removing on `admin_footer` hook.
*/
function wpforms_admin_hide_unrelated_notices() { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.MaxExceeded, Generic.Metrics.NestingLevel.MaxExceeded
if ( ! wpforms_is_admin_page() ) {
return;
}
global $wp_filter;
// Define rules to remove callbacks.
$rules = [
'user_admin_notices' => [], // remove all callbacks.
'admin_notices' => [],
'all_admin_notices' => [],
'admin_footer' => [
'render_delayed_admin_notices', // remove this particular callback.
],
];
// Extra deny callbacks (will be removed for each hook tag defined in $rules).
$common_deny_callbacks = [
'wpformsdb_admin_notice', // 'Database for WPForms' plugin.
];
$notice_types = array_keys( $rules );
foreach ( $notice_types as $notice_type ) {
if ( empty( $wp_filter[ $notice_type ]->callbacks ) || ! is_array( $wp_filter[ $notice_type ]->callbacks ) ) {
continue;
}
$remove_all_filters = empty( $rules[ $notice_type ] );
foreach ( $wp_filter[ $notice_type ]->callbacks as $priority => $hooks ) {
foreach ( $hooks as $name => $arr ) {
if ( is_object( $arr['function'] ) && is_callable( $arr['function'] ) ) {
if ( $remove_all_filters ) {
unset( $wp_filter[ $notice_type ]->callbacks[ $priority ][ $name ] );
}
continue;
}
$class = ! empty( $arr['function'][0] ) && is_object( $arr['function'][0] ) ? strtolower( get_class( $arr['function'][0] ) ) : '';
// Remove all callbacks except WPForms notices.
if ( $remove_all_filters && strpos( $class, 'wpforms' ) === false ) {
unset( $wp_filter[ $notice_type ]->callbacks[ $priority ][ $name ] );
continue;
}
$cb = is_array( $arr['function'] ) ? $arr['function'][1] : $arr['function'];
// Remove a specific callback.
if ( ! $remove_all_filters ) {
if ( in_array( $cb, $rules[ $notice_type ], true ) ) {
unset( $wp_filter[ $notice_type ]->callbacks[ $priority ][ $name ] );
}
continue;
}
// Remove non-WPForms callbacks from `$common_deny_callbacks` denylist.
if ( in_array( $cb, $common_deny_callbacks, true ) ) {
unset( $wp_filter[ $notice_type ]->callbacks[ $priority ][ $name ] );
}
}
}
}
}
add_action( 'admin_print_scripts', 'wpforms_admin_hide_unrelated_notices' );
/**
* Upgrade link used within the various admin pages.
*
* Previously was only included as a method in wpforms-lite.php, but made
* available globally in 1.3.9.
*
* @since 1.3.9
*
* @param string $medium URL parameter: utm_medium.
* @param string $content URL parameter: utm_content.
*
* @return string
*/
function wpforms_admin_upgrade_link( $medium = 'link', $content = '' ) {
$url = 'https://wpforms.com/lite-upgrade/';
if ( wpforms()->is_pro() ) {
$license_key = wpforms_get_license_key();
$url = add_query_arg(
'license_key',
sanitize_text_field( $license_key ),
'https://wpforms.com/pricing/'
);
}
// phpcs:ignore WPForms.Comments.PHPDocHooks.RequiredHookDocumentation
$upgrade = wpforms_utm_link( $url, apply_filters( 'wpforms_upgrade_link_medium', $medium ), $content );
/**
* Modify upgrade link.
*
* @since 1.5.1
*
* @param string $upgrade Upgrade links.
*/
return apply_filters( 'wpforms_upgrade_link', $upgrade );
}
/**
* Check the current PHP version and display a notice if on unsupported PHP.
*
* @since 1.4.0.1
* @since 1.5.0 Raising this awareness of old PHP version message from 5.2 to 5.3.
* @since 1.7.9 Raising this awareness of old PHP version message to 7.1.
* @since 1.8.4 Raising this awareness of old PHP version message to 7.3.
*/
function wpforms_check_php_version() {
// Display for PHP below 7.4.
if ( PHP_VERSION_ID >= 70400 ) {
return;
}
// Display for admins only.
if ( ! is_super_admin() ) {
return;
}
// Display on Dashboard page only.
if ( isset( $GLOBALS['pagenow'] ) && $GLOBALS['pagenow'] !== 'index.php' ) {
return;
}
// Display the notice, finally.
Notice::error(
'<p>' .
sprintf(
wp_kses( /* translators: %1$s - WPForms plugin name; %2$s - WPForms.com URL to a related doc. */
__( 'Your site is running an outdated version of PHP that is no longer supported and may cause issues with %1$s. <a href="%2$s" target="_blank" rel="noopener noreferrer">Read more</a> for additional information.', 'wpforms-lite' ),
[
'a' => [
'href' => [],
'target' => [],
'rel' => [],
],
]
),
'<strong>WPForms</strong>',
'https://wpforms.com/docs/supported-php-version/'
) .
'<br><br><em>' .
wp_kses(
__( '<strong>Please Note:</strong> Support for PHP 7.3 and below will be discontinued soon. After this, if no further action is taken, WPForms functionality will be disabled.', 'wpforms-lite' ),
[
'strong' => [],
'em' => [],
]
) .
'</em></p>'
);
}
add_action( 'admin_init', 'wpforms_check_php_version' );
/**
* Get an upgrade modal text.
*
* @since 1.4.4
*
* @param string $type Either "pro" or "elite". Default is "pro".
*
* @return string
*/
function wpforms_get_upgrade_modal_text( $type = 'pro' ) {
switch ( $type ) {
case 'elite':
$level = 'WPForms Elite';
break;
case 'pro':
default:
$level = 'WPForms Pro';
}
if ( wpforms()->is_pro() ) {
return '<p>' .
sprintf(
wp_kses( /* translators: %s - WPForms.com contact page URL. */
__( 'Thank you for considering upgrading. If you have any questions, please <a href="%s" target="_blank" rel="noopener noreferrer">let us know</a>.', 'wpforms-lite' ),
[
'a' => [
'href' => [],
'target' => [],
'rel' => [],
],
]
),
esc_url(
wpforms_utm_link(
'https://wpforms.com/contact/',
'Upgrade Follow Up Modal',
'Contact Support'
)
)
) .
'</p>' .
'<p>' .
wp_kses(
__( 'After upgrading, your license key will remain the same.<br>You may need to do a quick refresh to unlock your new addons. In your WordPress admin, go to <strong>WPForms &raquo; Settings</strong>. If you don\'t see your updated plan, click <em>refresh</em>.', 'wpforms-lite' ),
[
'strong' => [],
'br' => [],
'em' => [],
]
) .
'</p>' .
'<p>' .
sprintf(
wp_kses( /* translators: %s - WPForms.com upgrade from Lite to paid docs page URL. */
__( 'Check out <a href="%s" target="_blank" rel="noopener noreferrer">our documentation</a> for step-by-step instructions.', 'wpforms-lite' ),
[
'a' => [
'href' => [],
'target' => [],
'rel' => [],
],
]
),
'https://wpforms.com/docs/upgrade-wpforms-license/'
) .
'</p>';
}
return '<p>' .
sprintf(
wp_kses( /* translators: %s - WPForms.com contact page URL. */
__( 'If you have any questions or issues just <a href="%s" target="_blank" rel="noopener noreferrer">let us know</a>.', 'wpforms-lite' ),
[
'a' => [
'href' => [],
'target' => [],
'rel' => [],
],
]
),
esc_url(
wpforms_utm_link(
'https://wpforms.com/contact/',
'Upgrade Intention Alert',
'Upgrade Intention Alert'
)
)
) .
'</p>' .
'<p>' .
sprintf(
wp_kses( /* translators: %s - license level, WPForms Pro or WPForms Elite. */
__( 'After purchasing a license, just <strong>enter your license key on the WPForms Settings page</strong>. This will let your site automatically upgrade to %s! (Don\'t worry, all your forms and settings will be preserved.)', 'wpforms-lite' ),
[
'strong' => [],
'br' => [],
]
),
$level
) .
'</p>' .
'<p>' .
sprintf(
wp_kses( /* translators: %s - WPForms.com upgrade from Lite to paid docs page URL. */
__( 'Check out <a href="%s" target="_blank" rel="noopener noreferrer">our documentation</a> for step-by-step instructions.', 'wpforms-lite' ),
[
'a' => [
'href' => [],
'target' => [],
'rel' => [],
],
]
),
esc_url(
wpforms_utm_link(
'https://wpforms.com/docs/upgrade-wpforms-lite-paid-license/',
'Upgrade Intention Alert',
'Upgrade Documentation'
)
)
) .
'</p>';
}
/**
* Hide the wp-admin area "Version x.x" in footer on WPForms pages.
*
* @since 1.5.7
*
* @param string $text Default "Version x.x" or "Get Version x.x" text.
*
* @return string
*/
function wpforms_admin_hide_wp_version( $text ) {
// Reset text if we're not on a WPForms screen or page.
if ( wpforms_is_admin_page() ) {
return 'WPForms ' . WPFORMS_VERSION;
}
return $text;
}
add_filter( 'update_footer', 'wpforms_admin_hide_wp_version', PHP_INT_MAX );

View File

@@ -0,0 +1,834 @@
<?php
/**
* Ajax actions used in by admin.
*
* @since 1.0.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Save a form.
*
* @since 1.0.0
*/
function wpforms_save_form() {
// Run a security check.
if ( ! check_ajax_referer( 'wpforms-builder', 'nonce', false ) ) {
wp_send_json_error( esc_html__( 'Your session expired. Please reload the builder.', 'wpforms-lite' ) );
}
// Check for permissions.
if ( ! wpforms_current_user_can( 'edit_forms' ) ) {
wp_send_json_error( esc_html__( 'You are not allowed to perform this action.', 'wpforms-lite' ) );
}
// Check for form data.
if ( empty( $_POST['data'] ) ) {
wp_send_json_error( esc_html__( 'Something went wrong while performing this action.', 'wpforms-lite' ) );
}
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
$form_post = json_decode( wp_unslash( $_POST['data'] ) );
$data = [
'fields' => [],
];
if ( $form_post ) {
foreach ( $form_post as $post_input_data ) {
// For input names that are arrays (e.g. `menu-item-db-id[3][4][5]`),
// derive the array path keys via regex and set the value in $_POST.
preg_match( '#([^\[]*)(\[(.+)\])?#', $post_input_data->name, $matches );
$array_bits = [ $matches[1] ];
if ( isset( $matches[3] ) ) {
$array_bits = array_merge( $array_bits, explode( '][', $matches[3] ) );
}
$new_post_data = [];
// Build the new array value from leaf to trunk.
for ( $i = count( $array_bits ) - 1; $i >= 0; $i -- ) {
if ( $i === count( $array_bits ) - 1 ) {
$new_post_data[ $array_bits[ $i ] ] = wp_slash( $post_input_data->value );
} else {
$new_post_data = [
$array_bits[ $i ] => $new_post_data,
];
}
}
$data = array_replace_recursive( $data, $new_post_data );
}
}
// Get form tags.
$form_tags = isset( $data['settings']['form_tags_json'] ) ? json_decode( wp_unslash( $data['settings']['form_tags_json'] ), true ) : [];
// Clear not needed data.
unset( $data['settings']['form_tags_json'] );
// Store tags labels in the form settings.
$data['settings']['form_tags'] = wp_list_pluck( $form_tags, 'label' );
// Update form data.
$form_id = wpforms()->get( 'form' )->update( $data['id'], $data, [ 'context' => 'save_form' ] );
/**
* Fires after updating form data.
*
* @since 1.4.0
*
* @param int $form_id Form ID.
* @param array $data Form data.
*/
do_action( 'wpforms_builder_save_form', $form_id, $data );
if ( ! $form_id ) {
wp_send_json_error( esc_html__( 'Something went wrong while saving the form.', 'wpforms-lite' ) );
}
// Update form tags.
wp_set_post_terms(
$form_id,
wpforms()->get( 'forms_tags_ajax' )->get_processed_tags( $form_tags ),
WPForms_Form_Handler::TAGS_TAXONOMY
);
$response_data = [
'form_name' => esc_html( $data['settings']['form_title'] ),
'form_desc' => $data['settings']['form_desc'],
'redirect' => admin_url( 'admin.php?page=wpforms-overview' ),
];
/**
* Allows filtering ajax response data after form was saved.
*
* @since 1.5.1
*
* @param array $response_data The data to be sent in the response.
* @param int $form_id Form ID.
* @param array $data Form data.
*/
$response_data = apply_filters(
'wpforms_builder_save_form_response_data',
$response_data,
$form_id,
$data
);
wp_send_json_success( $response_data );
}
add_action( 'wp_ajax_wpforms_save_form', 'wpforms_save_form' );
/**
* Create a new form.
*
* @since 1.0.0
*/
function wpforms_new_form() { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh
check_ajax_referer( 'wpforms-builder', 'nonce' );
if ( empty( $_POST['title'] ) ) {
wp_send_json_error(
[
'error_type' => 'missing_form_title',
'message' => esc_html__( 'No form name provided.', 'wpforms-lite' ),
]
);
}
$form_title = sanitize_text_field( wp_unslash( $_POST['title'] ) );
$form_template = empty( $_POST['template'] ) ? 'blank' : sanitize_text_field( wp_unslash( $_POST['template'] ) );
if ( ! wpforms()->get( 'builder_templates' )->is_valid_template( $form_template ) ) {
wp_send_json_error(
[
'error_type' => 'invalid_template',
'message' => esc_html__( 'The template you selected is currently not available, but you can try again later. If you continue to have trouble, please reach out to support.', 'wpforms-lite' ),
]
);
}
$title_query = new WP_Query(
[
'post_type' => 'wpforms',
'title' => $form_title,
'posts_per_page' => 1,
'fields' => 'ids',
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
'no_found_rows' => true,
]
);
$title_exists = $title_query->post_count > 0;
$form_id = wpforms()->get( 'form' )->add(
$form_title,
[],
[
'template' => $form_template,
]
);
if ( $title_exists ) {
// Skip creating a revision for this action.
remove_action( 'post_updated', 'wp_save_post_revision' );
wp_update_post(
[
'ID' => $form_id,
'post_title' => $form_title . ' (ID #' . $form_id . ')',
]
);
// Restore the initial revisions state.
add_action( 'post_updated', 'wp_save_post_revision', 10, 1 );
}
if ( ! $form_id ) {
wp_send_json_error(
[
'error_type' => 'cant_create_form',
'message' => esc_html__( 'Error creating form.', 'wpforms-lite' ),
]
);
}
if ( wpforms_current_user_can( 'edit_form_single', $form_id ) ) {
wp_send_json_success(
[
'id' => $form_id,
'redirect' => add_query_arg(
[
'view' => 'fields',
'form_id' => $form_id,
'newform' => '1',
],
admin_url( 'admin.php?page=wpforms-builder' )
),
]
);
}
if ( wpforms_current_user_can( 'view_forms' ) ) {
wp_send_json_success( [ 'redirect' => admin_url( 'admin.php?page=wpforms-overview' ) ] );
}
wp_send_json_success( [ 'redirect' => admin_url() ] );
}
add_action( 'wp_ajax_wpforms_new_form', 'wpforms_new_form' );
/**
* Update form template.
*
* @since 1.0.0
*/
function wpforms_update_form_template() {
// Run a security check.
check_ajax_referer( 'wpforms-builder', 'nonce' );
// Check for form ID.
if ( empty( $_POST['form_id'] ) ) {
wp_send_json_error(
[
'error_type' => 'invalid_form_id',
'message' => esc_html__( 'No form ID provided.', 'wpforms-lite' ),
]
);
}
// Set initial variables.
$form_id = absint( $_POST['form_id'] );
$form_template = empty( $_POST['template'] ) ? 'blank' : sanitize_text_field( wp_unslash( $_POST['template'] ) );
// Check for valid template.
if ( ! wpforms()->get( 'builder_templates' )->is_valid_template( $form_template ) ) {
wp_send_json_error(
[
'error_type' => 'invalid_template',
'message' => esc_html__( 'The template you selected is currently not available, but you can try again later. If you continue to have trouble, please reach out to support.', 'wpforms-lite' ),
]
);
}
// Get current form data.
$data = wpforms()->get( 'form' )->get(
$form_id,
[
'content_only' => true,
]
);
// Get the cached data from the form template JSON.
$template_data = wpforms()->get( 'builder_templates' )->get_template( $form_template );
// If the template title is set, use it. Otherwise, clear the form title.
$template_title = ! empty( $template_data['name'] ) ? $template_data['name'] : '';
// If the form title is set, use it. Otherwise, use the template title.
$form_title = ! empty( $_POST['title'] ) ? sanitize_text_field( wp_unslash( $_POST['title'] ) ) : $template_title;
// If the these template titles are empty, use the form title.
$form_pages_title = $template_title ? $template_title : $form_title;
$form_conversational_title = ! empty( $template_data['data']['settings']['conversational_forms_title'] ) ? $template_data['data']['settings']['conversational_forms_title'] : $form_title;
// If these template slugs are empty, use the form title.
$form_conversational_slug = ! empty( $template_data['data']['settings']['conversational_forms_page_slug'] ) ? $template_data['data']['settings']['conversational_forms_page_slug'] : $form_title;
$form_pages_slug = ! empty( $template_data['data']['settings']['form_pages_page_slug'] ) ? $template_data['data']['settings']['form_pages_page_slug'] : $form_title;
// Loop over notifications.
$notifications = isset( $template_data['data']['settings']['notifications'] ) ? $template_data['data']['settings']['notifications'] : [];
foreach ( $notifications as $key => $notification ) {
// If the subject is empty, set it to an empty string.
$notification_subject = ! empty( $notification['subject'] ) ? sanitize_text_field( $notification['subject'] ) : '';
$data['settings']['notifications'][ $key ]['subject'] = $notification_subject;
}
// Loop over confirmations.
$confirmations = isset( $template_data['data']['settings']['confirmations'] ) ? $template_data['data']['settings']['confirmations'] : [];
foreach ( $confirmations as $key => $confirmation ) {
// If the message is empty, set it to an empty string.
$confirmation_message = ! empty( $confirmation['message'] ) ? wp_kses_post( $confirmation['message'] ) : '';
$data['settings']['confirmations'][ $key ]['message'] = $confirmation_message;
}
// Set updated form titles.
$data['settings']['form_title'] = sanitize_text_field( $form_title );
$data['settings']['form_pages_title'] = sanitize_text_field( $form_pages_title );
$data['settings']['conversational_forms_title'] = sanitize_text_field( $form_conversational_title );
// Set updated form slugs.
$data['settings']['form_pages_page_slug'] = sanitize_title( $form_pages_slug );
$data['settings']['conversational_forms_page_slug'] = sanitize_title( $form_conversational_slug );
// Try to update the form.
$updated = (bool) wpforms()->get( 'form' )->update(
$form_id,
$data,
[
'template' => $form_template,
]
);
// If the form was updated, return the form ID and redirect to the form builder.
if ( $updated ) {
wp_send_json_success(
[
'id' => $form_id,
'redirect' => add_query_arg(
[
'view' => 'fields',
'form_id' => $form_id,
],
admin_url( 'admin.php?page=wpforms-builder' )
),
]
);
}
// Otherwise, return an error.
wp_send_json_error(
[
'error_type' => 'cant_update',
'message' => esc_html__( 'Error updating form template.', 'wpforms-lite' ),
]
);
}
add_action( 'wp_ajax_wpforms_update_form_template', 'wpforms_update_form_template' );
/**
* Form Builder update next field ID.
*
* @since 1.2.9
*/
function wpforms_builder_increase_next_field_id() {
// Run a security check.
check_ajax_referer( 'wpforms-builder', 'nonce' );
// Check for permissions.
if ( ! wpforms_current_user_can( 'edit_forms' ) ) {
wp_send_json_error();
}
// Check for required items.
if ( empty( $_POST['form_id'] ) ) {
wp_send_json_error();
}
$args = [];
// In the case of duplicating the Layout field that contains a bunch of fields,
// we need to set the next `field_id` to the desired value which is passed via POST argument.
if ( ! empty( $_POST['field_id'] ) ) {
$args['field_id'] = absint( $_POST['field_id'] );
}
wpforms()->get( 'form' )->next_field_id( absint( $_POST['form_id'] ), $args );
wp_send_json_success();
}
add_action( 'wp_ajax_wpforms_builder_increase_next_field_id', 'wpforms_builder_increase_next_field_id' );
/**
* Form Builder Dynamic Choices option toggle.
*
* This can be triggered with select/radio/checkbox fields.
*
* @since 1.2.8
*/
function wpforms_builder_dynamic_choices() {
// Run a security check.
check_ajax_referer( 'wpforms-builder', 'nonce' );
// Check for permissions.
if ( ! wpforms_current_user_can( 'edit_forms' ) ) {
wp_send_json_error();
}
// Check for valid/required items.
if ( ! isset( $_POST['field_id'] ) || empty( $_POST['type'] ) || ! in_array( $_POST['type'], [ 'post_type', 'taxonomy' ], true ) ) {
wp_send_json_error();
}
$type = sanitize_key( $_POST['type'] );
$id = absint( $_POST['field_id'] );
// Fetch the option row HTML to be returned to the builder.
$field = new WPForms_Field_Select( false );
$field_args = [
'id' => $id,
'dynamic_choices' => $type,
];
$option_row = $field->field_option( 'dynamic_choices_source', $field_args, [], false );
wp_send_json_success(
[
'markup' => $option_row,
]
);
}
add_action( 'wp_ajax_wpforms_builder_dynamic_choices', 'wpforms_builder_dynamic_choices' );
/**
* Form Builder Dynamic Choices Source option toggle.
*
* This can be triggered with select/radio/checkbox fields.
*
* @since 1.2.8
*/
function wpforms_builder_dynamic_source() {
// Run a security check.
check_ajax_referer( 'wpforms-builder', 'nonce' );
// Check for permissions.
if ( ! wpforms_current_user_can( 'edit_forms' ) ) {
wp_send_json_error();
}
// Check for required items.
if ( ! isset( $_POST['field_id'] ) || empty( $_POST['form_id'] ) || empty( $_POST['type'] ) || empty( $_POST['source'] ) ) {
wp_send_json_error();
}
$type = sanitize_key( $_POST['type'] );
$source = sanitize_key( $_POST['source'] );
$id = absint( $_POST['field_id'] );
$form_id = absint( $_POST['form_id'] );
$items = [];
$total = 0;
$source_name = '';
$type_name = '';
if ( $type === 'post_type' ) {
$type_name = esc_html__( 'post type', 'wpforms-lite' );
$args = [
'post_type' => $source,
'posts_per_page' => 20,
'orderby' => 'title',
'order' => 'ASC',
];
$posts = wpforms_get_hierarchical_object(
apply_filters(
'wpforms_dynamic_choice_post_type_args',
$args,
[
'id' => $id,
],
$form_id
),
true
);
$total = wp_count_posts( $source );
$total = $total->publish;
$pt = get_post_type_object( $source );
$source_name = '';
if ( $pt !== null ) {
$source_name = $pt->labels->name;
}
foreach ( $posts as $post ) {
$items[] = esc_html( wpforms_get_post_title( $post ) );
}
} elseif ( $type === 'taxonomy' ) {
$type_name = esc_html__( 'taxonomy', 'wpforms-lite' );
$args = [
'taxonomy' => $source,
'hide_empty' => false,
'number' => 20,
];
$terms = wpforms_get_hierarchical_object(
apply_filters(
'wpforms_dynamic_choice_taxonomy_args',
$args,
[
'id' => $id,
],
$form_id
),
true
);
$total = wp_count_terms( $source );
$tax = get_taxonomy( $source );
$source_name = $tax->labels->name;
foreach ( $terms as $term ) {
$items[] = esc_html( wpforms_get_term_name( $term ) );
}
}
if ( empty( $items ) ) {
$items = [];
}
wp_send_json_success(
[
'items' => $items,
'source' => $source,
'source_name' => $source_name,
'total' => $total,
'type' => $type,
'type_name' => $type_name,
]
);
}
add_action( 'wp_ajax_wpforms_builder_dynamic_source', 'wpforms_builder_dynamic_source' );
/**
* Perform test connection to verify that the current web host can successfully
* make outbound SSL connections.
*
* @since 1.4.5
*/
function wpforms_verify_ssl() {
// Run a security check.
check_ajax_referer( 'wpforms-admin', 'nonce' );
// Check for permissions.
if ( ! wpforms_current_user_can() ) {
wp_send_json_error(
[
'msg' => esc_html__( 'You do not have permission to perform this operation.', 'wpforms-lite' ),
]
);
}
$response = wp_remote_post( 'https://wpforms.com/connection-test.php' );
if ( 200 === wp_remote_retrieve_response_code( $response ) ) {
wp_send_json_success(
[
'msg' => esc_html__( 'Success! Your server can make SSL connections.', 'wpforms-lite' ),
]
);
}
wp_send_json_error(
[
'msg' => esc_html__( 'There was an error and the connection failed. Please contact your web host with the technical details below.', 'wpforms-lite' ),
'debug' => '<pre>' . print_r( map_deep( $response, 'wp_strip_all_tags' ), true ) . '</pre>',
]
);
}
add_action( 'wp_ajax_wpforms_verify_ssl', 'wpforms_verify_ssl' );
/**
* Deactivate addon.
*
* @since 1.0.0
* @since 1.6.2.3 Updated the permissions checking.
*/
function wpforms_deactivate_addon() {
// Run a security check.
check_ajax_referer( 'wpforms-admin', 'nonce' );
// Check for permissions.
if ( ! current_user_can( 'deactivate_plugins' ) ) {
wp_send_json_error( esc_html__( 'Plugin deactivation is disabled for you on this site.', 'wpforms-lite' ) );
}
$type = empty( $_POST['type'] ) ? 'addon' : sanitize_key( $_POST['type'] );
if ( isset( $_POST['plugin'] ) ) {
$plugin = sanitize_text_field( wp_unslash( $_POST['plugin'] ) );
deactivate_plugins( $plugin );
do_action( 'wpforms_plugin_deactivated', $plugin );
if ( $type === 'plugin' ) {
wp_send_json_success( esc_html__( 'Plugin deactivated.', 'wpforms-lite' ) );
} else {
wp_send_json_success( esc_html__( 'Addon deactivated.', 'wpforms-lite' ) );
}
}
wp_send_json_error( esc_html__( 'Could not deactivate the addon. Please deactivate from the Plugins page.', 'wpforms-lite' ) );
}
add_action( 'wp_ajax_wpforms_deactivate_addon', 'wpforms_deactivate_addon' );
/**
* Activate addon.
*
* @since 1.0.0
* @since 1.6.2.3 Updated the permissions checking.
*/
function wpforms_activate_addon() {
// Run a security check.
check_ajax_referer( 'wpforms-admin', 'nonce' );
// Check for permissions.
if ( ! current_user_can( 'activate_plugins' ) ) {
wp_send_json_error( esc_html__( 'Plugin activation is disabled for you on this site.', 'wpforms-lite' ) );
}
$success_messages = [
'plugin' => __( 'Plugin activated.', 'wpforms-lite' ),
'addon' => __( 'Addon activated.', 'wpforms-lite' ),
];
$error_messages = [
'plugin' => __( 'Could not activate the plugin. Please activate it on the Plugins page.', 'wpforms-lite' ),
'addon' => __( 'Could not activate the addon. Please activate it on the Plugins page.', 'wpforms-lite' ),
];
$type = ! empty( $_POST['type'] ) ? sanitize_key( $_POST['type'] ) : 'addon';
$success_message = $success_messages[ $type ];
$error_message = $error_messages[ $type ];
if ( isset( $_POST['plugin'] ) ) {
$plugin = sanitize_text_field( wp_unslash( $_POST['plugin'] ) );
$activate = wpforms_activate_plugin( $plugin );
/**
* Fire after plugin activating via the WPForms installer.
*
* @since 1.6.3.1
*
* @param string $plugin Path to the plugin file relative to the plugins' directory.
*/
do_action( 'wpforms_plugin_activated', $plugin );
if ( $activate === null ) {
wp_send_json_success( wp_kses_post( $success_message ) );
}
$error_message = $activate->get_error_message();
}
wp_send_json_error( wp_kses_post( $error_message ) );
}
add_action( 'wp_ajax_wpforms_activate_addon', 'wpforms_activate_addon' );
/**
* Install addon.
*
* @since 1.0.0
* @since 1.6.2.3 Updated the permissions checking.
*/
function wpforms_install_addon() {
// Run a security check.
check_ajax_referer( 'wpforms-admin', 'nonce' );
$generic_error = esc_html__( 'There was an error while performing your request.', 'wpforms-lite' );
$type = ! empty( $_POST['type'] ) ? sanitize_key( $_POST['type'] ) : 'addon';
// Check if new installations are allowed.
if ( ! wpforms_can_install( $type ) ) {
wp_send_json_error( $generic_error );
}
$error = $type === 'plugin'
? esc_html__( 'Could not install the plugin. Please download and install it manually.', 'wpforms-lite' )
: sprintf(
wp_kses( /* translators: %1$s - addon download URL, %2$s - link to manual installation guide. */
__( 'Could not install the addon. Please <a href="%1$s" target="_blank" rel="noopener noreferrer">download it from wpforms.com</a> and <a href="%2$s" target="_blank" rel="noopener noreferrer">install it manually</a>.', 'wpforms-lite' ),
[
'a' => [
'href' => true,
'target' => true,
'rel' => true,
],
]
),
'https://wpforms.com/account/licenses/',
'https://wpforms.com/docs/how-to-manually-install-addons-in-wpforms/'
);
$plugin_url = ! empty( $_POST['plugin'] ) ? esc_url_raw( wp_unslash( $_POST['plugin'] ) ) : '';
if ( empty( $plugin_url ) ) {
wp_send_json_error( $error );
}
$args_str = ! empty( $_POST['args'] ) ? sanitize_text_field( wp_unslash( $_POST['args'] ) ) : '';
$args = json_decode( $args_str, true ) ?? [];
// Set the current screen to avoid undefined notices.
set_current_screen( 'wpforms_page_wpforms-settings' );
// Prepare variables.
$url = esc_url_raw(
add_query_arg(
[
'page' => 'wpforms-addons',
],
admin_url( 'admin.php' )
)
);
ob_start();
$creds = request_filesystem_credentials( $url, '', false, false, null );
// Hide the filesystem credentials form.
ob_end_clean();
// Check for file system permissions.
if ( $creds === false ) {
wp_send_json_error( $error );
}
if ( ! WP_Filesystem( $creds ) ) {
wp_send_json_error( $error );
}
/*
* We do not need any extra credentials if we have gotten this far, so let's install the plugin.
*/
require_once WPFORMS_PLUGIN_DIR . 'includes/admin/class-install-skin.php';
// Do not allow WordPress to search/download translations, as this will break JS output.
remove_action( 'upgrader_process_complete', [ 'Language_Pack_Upgrader', 'async_upgrade' ], 20 );
// Create the plugin upgrader with our custom skin.
$installer = new WPForms\Helpers\PluginSilentUpgrader( new WPForms_Install_Skin() );
// Error check.
if ( ! method_exists( $installer, 'install' ) ) {
wp_send_json_error( $error );
}
$installer->install( $plugin_url, $args );
// Flush the cache and return the newly installed plugin basename.
wp_cache_flush();
$plugin_basename = $installer->plugin_info();
if ( empty( $plugin_basename ) ) {
wp_send_json_error( $error );
}
$result = [
'msg' => $generic_error,
'is_activated' => false,
'basename' => $plugin_basename,
];
// Check for permissions.
if ( ! current_user_can( 'activate_plugins' ) ) {
$result['msg'] = $type === 'plugin' ? esc_html__( 'Plugin installed.', 'wpforms-lite' ) : esc_html__( 'Addon installed.', 'wpforms-lite' );
wp_send_json_success( $result );
}
// Activate the plugin silently.
$activated = activate_plugin( $plugin_basename );
if ( ! is_wp_error( $activated ) ) {
/**
* Fire after plugin activating via the WPForms installer.
*
* @since 1.7.0
*
* @param string $plugin_basename Path to the plugin file relative to the plugins directory.
*/
do_action( 'wpforms_plugin_activated', $plugin_basename );
$result['is_activated'] = true;
$result['msg'] = $type === 'plugin' ? esc_html__( 'Plugin installed & activated.', 'wpforms-lite' ) : esc_html__( 'Addon installed & activated.', 'wpforms-lite' );
wp_send_json_success( $result );
}
// Fallback error just in case.
wp_send_json_error( $result );
}
add_action( 'wp_ajax_wpforms_install_addon', 'wpforms_install_addon' );
/**
* Search pages for dropdown.
*
* @since 1.7.9
*/
function wpforms_ajax_search_pages_for_dropdown() {
// Run a security check.
if ( ! check_ajax_referer( 'wpforms-builder', 'nonce', false ) ) {
wp_send_json_error( esc_html__( 'Your session expired. Please reload the builder.', 'wpforms-lite' ) );
}
if ( ! array_key_exists( 'search', $_GET ) ) {
wp_send_json_error( esc_html__( 'Incorrect usage of this operation.', 'wpforms-lite' ) );
}
$result_pages = wpforms_search_pages_for_dropdown(
sanitize_text_field( wp_unslash( $_GET['search'] ) )
);
if ( empty( $result_pages ) ) {
wp_send_json_success( [] );
}
wp_send_json_success( $result_pages );
}
add_action( 'wp_ajax_wpforms_ajax_search_pages_for_dropdown', 'wpforms_ajax_search_pages_for_dropdown' );

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,663 @@
<?php
use WPForms\Admin\Education\Helpers;
/**
* Output fields to be used on panels (settings etc).
*
* @since 1.0.0
*
* @param string $option
* @param string $panel
* @param string $field
* @param array $form_data
* @param string $label
* @param array $args
* @param bool $echo
*
* @return string
*/
function wpforms_panel_field( $option, $panel, $field, $form_data, $label, $args = [], $echo = true ) {
// Required params.
if ( empty( $option ) || empty( $panel ) || empty( $field ) ) {
return '';
}
// Setup basic vars.
$panel = esc_attr( $panel );
$field = esc_attr( $field );
$panel_id = sanitize_html_class( $panel );
$parent = ! empty( $args['parent'] ) ? esc_attr( $args['parent'] ) : '';
$subsection = ! empty( $args['subsection'] ) ? esc_attr( $args['subsection'] ) : '';
$index = isset( $args['index'] ) ? esc_attr( $args['index'] ) : '';
$index = is_numeric( $index ) ? absint( $index ) : $index;
$label = ! empty( $label ) ? wp_kses( $label, [ 'span' => [ 'class' => [] ] ] ) : '';
$class = ! empty( $args['class'] ) ? wpforms_sanitize_classes( $args['class'] ) : '';
$input_class = ! empty( $args['input_class'] ) ? wpforms_sanitize_classes( $args['input_class'] ) : '';
$default = isset( $args['default'] ) ? $args['default'] : '';
$placeholder = ! empty( $args['placeholder'] ) ? esc_attr( $args['placeholder'] ) : '';
$data_attr = '';
$output = '';
$smarttags_toggle = '';
$input_id = sprintf( 'wpforms-panel-field-%s-%s', sanitize_html_class( $panel_id ), sanitize_html_class( $field ) );
if ( ! empty( $args['input_id'] ) ) {
$input_id = esc_attr( $args['input_id'] );
}
if ( ! empty( $args['smarttags'] ) ) {
$type = ! empty( $args['smarttags']['type'] ) ? esc_attr( $args['smarttags']['type'] ) : 'fields';
$fields = ! empty( $args['smarttags']['fields'] ) ? esc_attr( $args['smarttags']['fields'] ) : '';
$smarttags_toggle = sprintf(
'<a href="#" class="toggle-smart-tag-display toggle-unfoldable-cont" data-type="%s" data-fields="%s">
<i class="fa fa-tags"></i><span>%s</span>
</a>',
esc_attr( $type ),
esc_attr( $fields ),
esc_html__( 'Show Smart Tags', 'wpforms-lite' )
);
}
if ( ! empty( $args['pro_badge'] ) ) {
$label .= Helpers::get_badge( 'Pro', 'sm', 'inline', 'silver' );
}
// Check if we should store values in a parent array.
if ( ! empty( $parent ) ) {
if ( $subsection && ! wpforms_is_empty_string( $index ) ) {
$field_name = sprintf( '%s[%s][%s][%s][%s]', $parent, $panel, $subsection, $index, $field );
$value = isset( $form_data[ $parent ][ $panel ][ $subsection ][ $index ][ $field ] ) ? $form_data[ $parent ][ $panel ][ $subsection ][ $index ][ $field ] : $default;
$input_id = sprintf( 'wpforms-panel-field-%s-%s-%s-%s', sanitize_html_class( $panel_id ), sanitize_html_class( $subsection ), sanitize_html_class( $index ), sanitize_html_class( $field ) );
} elseif ( ! empty( $subsection ) ) {
$field_name = sprintf( '%s[%s][%s][%s]', $parent, $panel, $subsection, $field );
$value = isset( $form_data[ $parent ][ $panel ][ $subsection ][ $field ] ) ? $form_data[ $parent ][ $panel ][ $subsection ][ $field ] : $default;
$input_id = sprintf( 'wpforms-panel-field-%s-%s-%s', sanitize_html_class( $panel_id ), sanitize_html_class( $subsection ), sanitize_html_class( $field ) );
$panel_id = sanitize_html_class( $panel . '-' . $subsection );
} else {
$field_name = sprintf( '%s[%s][%s]', $parent, $panel, $field );
$value = isset( $form_data[ $parent ][ $panel ][ $field ] ) ? $form_data[ $parent ][ $panel ][ $field ] : $default;
}
} else {
$field_name = sprintf( '%s[%s]', $panel, $field );
$value = isset( $form_data[ $panel ][ $field ] ) ? $form_data[ $panel ][ $field ] : $default;
}
if ( isset( $args['field_name'] ) ) {
$field_name = $args['field_name'];
}
if ( isset( $args['value'] ) ) {
$value = $args['value'];
}
// Check for data attributes.
if ( ! empty( $args['data'] ) ) {
foreach ( $args['data'] as $key => $val ) {
if ( is_array( $val ) ) {
$val = wp_json_encode( $val );
}
$data_attr .= ' data-' . $key . '=\'' . $val . '\'';
}
}
// Check for readonly inputs.
if ( ! empty( $args['readonly'] ) ) {
$data_attr .= 'readonly';
}
// Determine what field type to output.
switch ( $option ) {
// Text input.
case 'text':
// Handle min and max attributes for number fields.
if ( ! empty( $args['type'] ) && $args['type'] === 'number' ) {
if ( isset( $args['min'] ) && is_int( $args['min'] ) ) {
$data_attr .= sprintf( ' min="%1$d" oninput="validity.valid||(value=\'%1$d\');" ', esc_attr( $args['min'] ) );
}
if ( isset( $args['max'] ) && is_int( $args['max'] ) ) {
$data_attr .= sprintf( ' max="%1$d" oninput="validity.valid||(value=\'%1$d\');" ', esc_attr( $args['max'] ) );
}
}
$output = sprintf(
'<input type="%s" id="%s" name="%s" value="%s" placeholder="%s" class="%s" %s>',
! empty( $args['type'] ) ? esc_attr( $args['type'] ) : 'text',
$input_id,
$field_name,
esc_attr( $value ),
$placeholder,
$input_class,
$data_attr
);
break;
// Textarea.
case 'textarea':
$output = sprintf(
'<textarea id="%s" name="%s" rows="%d" placeholder="%s" class="%s" %s>%s</textarea>',
$input_id,
$field_name,
! empty( $args['rows'] ) ? (int) $args['rows'] : '3',
$placeholder,
$input_class,
$data_attr,
esc_textarea( $value )
);
break;
// TinyMCE.
case 'tinymce':
$id = str_replace( '-', '_', $input_id );
$args['tinymce']['textarea_name'] = $field_name;
$args['tinymce']['teeny'] = true;
$args['tinymce'] = wp_parse_args(
$args['tinymce'],
[
'media_buttons' => false,
'teeny' => true,
]
);
ob_start();
wp_editor( $value, $id, $args['tinymce'] );
$output = ob_get_clean();
break;
// Checkbox.
case 'checkbox':
$output = sprintf(
'<input type="checkbox" id="%s" name="%s" value="1" class="%s" %s %s>',
$input_id,
$field_name,
$input_class,
checked( '1', $value, false ),
$data_attr
);
$output .= sprintf(
'<label for="%s" class="inline">%s',
$input_id,
$label
);
if ( ! empty( $args['before_tooltip'] ) ) {
$output .= $args['before_tooltip'];
}
if ( ! empty( $args['tooltip'] ) ) {
$output .= sprintf( '<i class="fa fa-question-circle-o wpforms-help-tooltip" title="%s"></i>', esc_attr( $args['tooltip'] ) );
}
$output .= '</label>';
break;
// Toggle.
case 'toggle':
$toggle_args = $args;
$toggle_args['input-class'] = $input_class;
$output = wpforms_panel_field_toggle_control( $toggle_args, $input_id, $field_name, $label, $value, $data_attr );
break;
// Radio.
case 'radio':
$options = $args['options'];
$radio_counter = 1;
$output = '';
foreach ( $options as $key => $item ) {
if ( empty( $item['label'] ) ) {
continue;
}
$item_value = ! empty( $item['value'] ) ? $item['value'] : $key;
$output .= '<span class="row">';
if ( ! empty( $item['pre_label'] ) ) {
$output .= '<label>' . $item['pre_label'];
}
$output .= sprintf(
'<input type="radio" id="%s-%d" name="%s" value="%s" class="%s" %s %s>',
$input_id,
$radio_counter,
$field_name,
$item_value,
$input_class,
checked( $item_value, $value, false ),
$data_attr
);
if ( empty( $item['pre_label'] ) ) {
$output .= sprintf(
'<label for="%s-%d" class="inline">%s',
$input_id,
$radio_counter,
$item['label']
);
} else {
$output .= '<span class="wpforms-panel-field-radio-label">' . $item['label'] . '</span>';
}
if ( ! empty( $item['tooltip'] ) ) {
$output .= sprintf( '<i class="fa fa-question-circle-o wpforms-help-tooltip" title="%s"></i>', esc_attr( $item['tooltip'] ) );
}
$output .= '</label></span>';
$radio_counter ++;
}
if ( ! empty( $output ) ) {
$output = '<div class="wpforms-panel-field-radio-container">' . $output . '</div>';
}
break;
// Select.
case 'select':
if ( empty( $args['options'] ) && empty( $args['field_map'] ) && empty( $args['multiple'] ) ) {
return '';
}
if ( ! empty( $args['field_map'] ) ) {
$options = [];
$available_fields = wpforms_get_form_fields( $form_data, $args['field_map'] );
if ( ! empty( $available_fields ) ) {
foreach ( $available_fields as $id => $available_field ) {
$options[ $id ] = ! empty( $available_field['label'] )
? esc_attr( $available_field['label'] )
: sprintf( /* translators: %d - field ID. */
esc_html__( 'Field #%d', 'wpforms-lite' ),
absint( $id )
);
}
}
$input_class .= ' wpforms-field-map-select';
$data_attr .= ' data-field-map-allowed="' . implode( ' ', $args['field_map'] ) . '"';
if ( ! empty( $placeholder ) ) {
$data_attr .= ' data-field-map-placeholder="' . esc_attr( $placeholder ) . '"';
}
} else {
$options = $args['options'];
}
if ( array_key_exists( 'choicesjs', $args ) && is_array( $args['choicesjs'] ) ) {
$input_class .= ' choicesjs-select';
$data_attr .= ! empty( $args['choicesjs']['use_ajax'] ) ? ' data-choicesjs-use-ajax=1' : '';
$data_attr .= ! empty( $args['choicesjs']['callback_fn'] ) ? ' data-choicesjs-callback-fn="' . esc_attr( $args['choicesjs']['callback_fn'] ) . '"' : '';
}
if ( ! empty( $args['multiple'] ) ) {
$data_attr .= ' multiple';
}
$output = sprintf(
'<select id="%s" name="%s" class="%s" %s>',
$input_id,
$field_name,
esc_attr( $input_class ),
$data_attr
);
if ( ! empty( $placeholder ) ) {
$output .= '<option value="">' . $placeholder . '</option>';
}
// This argument is used to disable some options, it takes an array of option values.
// For instance, if you want to disable options with value '1' and '2', you should pass array( '1', '2' ).
$disabled_options = ! empty( $args['disabled_options'] ) ? (array) $args['disabled_options'] : [];
foreach ( $options as $key => $item ) {
// If the option is disabled, we add the disabled attribute.
$disabled = in_array( $key, $disabled_options, true ) ? 'disabled' : '';
// Disabled options cannot be selected, so we bail early.
if ( ! empty( $disabled ) ) {
$output .= sprintf(
'<option value="%s" %s>%s</option>',
esc_attr( $key ),
$disabled,
$item
);
continue;
}
if ( is_array( $value ) ) {
$selected = in_array( $key, $value, true ) ? 'selected' : '';
} else {
$selected = selected( $key, $value, false );
}
$output .= sprintf(
'<option value="%s" %s>%s</option>',
esc_attr( $key ),
$selected,
$item
);
}
$output .= '</select>';
break;
case 'color':
$class .= ' wpforms-panel-field-colorpicker';
$input_class .= ' wpforms-color-picker';
$output = sprintf(
'<input type="text" id="%s" name="%s" value="%s" class="%s" %s>',
$input_id,
$field_name,
esc_attr( $value ),
wpforms_sanitize_classes( $input_class, false ),
$data_attr
);
break;
}
// Put the pieces together.
$field_open = sprintf(
'<div id="%s-wrap" class="wpforms-panel-field %s %s">',
$input_id,
$class,
'wpforms-panel-field-' . sanitize_html_class( $option )
);
$field_open .= ! empty( $args['before'] ) ? $args['before'] : '';
if ( $option !== 'toggle' && $option !== 'checkbox' && ! empty( $label ) ) {
$field_label = sprintf(
'<label for="%s">%s',
$input_id,
$label
);
if ( ! empty( $args['tooltip'] ) ) {
$field_label .= sprintf( '<i class="fa fa-question-circle-o wpforms-help-tooltip" title="%s"></i>', esc_attr( $args['tooltip'] ) );
}
if ( ! empty( $args['after_tooltip'] ) ) {
$field_label .= $args['after_tooltip'];
}
if ( $smarttags_toggle && ! ( $option === 'textarea' && ! empty( $args['tinymce'] ) ) ) {
$field_label .= $smarttags_toggle;
}
$field_label .= '</label>';
if ( ! empty( $args['after_label'] ) ) {
$field_label .= $args['after_label'];
}
} else {
$field_label = '';
}
$field_close = '';
if ( $smarttags_toggle && $option === 'textarea' && ! empty( $args['tinymce'] ) ) {
$field_close .= $smarttags_toggle;
}
$field_close .= ! empty( $args['after'] ) ? $args['after'] : '';
$field_close .= '</div>';
$output = $field_open . $field_label . $output . $field_close;
// Wash our hands.
if ( $echo ) {
echo $output;
} else {
return $output;
}
}
/**
* Create toggle control.
*
* It's like a regular checkbox but with a modern visual appearance.
*
* @since 1.6.8
*
* @param array $args Arguments array.
*
* @type bool $status If `true`, control will display the current status next to the toggle.
* @type string $status-on Status `On` text. By default `On`.
* @type string $status-off Status `Off` text. By default `Off`.
* @type bool $label-hide If `true` then label will not display.
* @type string $tooltip Tooltip text.
* @type string $input-class CSS class for the hidden `<input type=checkbox>`.
* @type string $control-class CSS class for the wrapper `<span>`.
*
* @param string $input_id Input ID.
* @param string $field_name Field name.
* @param string $label Label text. Can contain HTML in order to display additional badges.
* @param mixed $value Value.
* @param string $data_attr Attributes.
*
* @return string
*/
function wpforms_panel_field_toggle_control( $args, $input_id, $field_name, $label, $value, $data_attr ) {
$checked = checked( true, (bool) $value, false );
$status = '';
if ( ! empty( $args['status'] ) ) {
$status_on = ! empty( $args['status-on'] ) ? $args['status-on'] : esc_html__( 'On', 'wpforms-lite' );
$status_off = ! empty( $args['status-off'] ) ? $args['status-off'] : esc_html__( 'Off', 'wpforms-lite' );
$status = sprintf(
'<label
for="%s"
class="wpforms-toggle-control-status"
data-on="%s"
data-off="%s">
%s
</label>',
esc_attr( $input_id ),
esc_attr( $status_on ),
esc_attr( $status_off ),
esc_html( $value ? $status_on : $status_off )
);
}
$label_html = empty( $args['label-hide'] ) && ! empty( $label ) ?
sprintf(
'<label for="%s" class="wpforms-toggle-control-label">%s</label>',
esc_attr( $input_id ),
$label
) : '';
$label_html .= isset( $args['tooltip'] ) ?
sprintf(
'<i class="fa fa-question-circle-o wpforms-help-tooltip" title="%s"></i>',
esc_attr( $args['tooltip'] )
) : '';
$label_left = ! empty( $args['label-left'] ) ? $label_html . $status : '';
$label_right = empty( $args['label-left'] ) ? $status . $label_html : '';
$title = isset( $args['title'] ) ? ' title="' . esc_attr( $args['title'] ) . '"' : '';
$control_class = ! empty( $args['control-class'] ) ? $args['control-class'] : '';
$input_class = ! empty( $args['input-class'] ) ? $args['input-class'] : '';
return sprintf(
'<span class="wpforms-toggle-control %8$s" %9$s>
%1$s
<input type="checkbox" id="%2$s" name="%3$s" class="%7$s" value="1" %4$s %5$s>
<label class="wpforms-toggle-control-icon" for="%2$s"></label>
%6$s
</span>',
$label_left,
esc_attr( $input_id ),
esc_attr( $field_name ),
$checked,
$data_attr,
$label_right,
wpforms_sanitize_classes( $input_class ),
wpforms_sanitize_classes( $control_class ),
$title
);
}
/**
* Get settings block state, whether it's opened or closed.
*
* @since 1.4.8
*
* @param int $form_id
* @param int $block_id
* @param string $block_type
*
* @return string
*/
function wpforms_builder_settings_block_get_state( $form_id, $block_id, $block_type ) {
$form_id = absint( $form_id );
$block_id = absint( $block_id );
$block_type = sanitize_key( $block_type );
$state = 'opened';
$all_states = get_user_meta( get_current_user_id(), 'wpforms_builder_settings_collapsable_block_states', true );
if ( empty( $all_states ) ) {
return $state;
}
if (
is_array( $all_states ) &&
! empty( $all_states[ $form_id ][ $block_type ][ $block_id ] ) &&
'closed' === $all_states[ $form_id ][ $block_type ][ $block_id ]
) {
$state = 'closed';
}
// Backward compatibility for notifications.
if ( 'notification' === $block_type && 'closed' !== $state ) {
$notification_states = get_user_meta( get_current_user_id(), 'wpforms_builder_notification_states', true );
}
if (
! empty( $notification_states[ $form_id ][ $block_id ] ) &&
'closed' === $notification_states[ $form_id ][ $block_id ]
) {
$state = 'closed';
}
if ( 'notification' === $block_type ) {
// Backward compatibility for notifications.
return apply_filters( 'wpforms_builder_notification_get_state', $state, $form_id, $block_id );
}
return apply_filters( 'wpforms_builder_settings_block_get_state', $state, $form_id, $block_id, $block_type );
}
/**
* Get the list of allowed tags, used in pair with wp_kses() function.
* This allows getting rid of all potentially harmful HTML tags and attributes.
*
* @since 1.5.9
*
* @return array Allowed Tags.
*/
function wpforms_builder_preview_get_allowed_tags() {
static $allowed_tags;
if ( ! empty( $allowed_tags ) ) {
return $allowed_tags;
}
$atts = [ 'align', 'class', 'type', 'id', 'for', 'style', 'src', 'rel', 'href', 'target', 'value', 'width', 'height' ];
$tags = [ 'label', 'iframe', 'style', 'button', 'strong', 'small', 'table', 'span', 'abbr', 'code', 'pre', 'div', 'img', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ol', 'ul', 'li', 'em', 'hr', 'br', 'th', 'tr', 'td', 'p', 'a', 'b', 'i' ];
$allowed_atts = array_fill_keys( $atts, [] );
$allowed_tags = array_fill_keys( $tags, $allowed_atts );
return $allowed_tags;
}
/**
* Output builder panel fields group wrapper.
*
* @since 1.6.6
*
* @param string $inner Inner HTML to wrap.
* @param array $args Array of arguments.
* @param bool $echo Flag to display.
*
* @return string
*/
function wpforms_panel_fields_group( $inner, $args = [], $echo = true ) {
$group = ! empty( $args['group'] ) ? $args['group'] : '';
$unfoldable = ! empty( $args['unfoldable'] );
$default = ( ! empty( $args['default'] ) && $args['default'] === 'opened' ) ? ' opened' : '';
$opened = ! empty( $_COOKIE[ 'wpforms_fields_group_' . $group ] ) && $_COOKIE[ 'wpforms_fields_group_' . $group ] === 'true' ? ' opened' : $default;
$class = ! empty( $args['class'] ) ? wpforms_sanitize_classes( $args['class'] ) : '';
$output = sprintf(
'<div class="wpforms-panel-fields-group %1$s%2$s"%3$s>',
$class,
$unfoldable ? ' unfoldable' . $opened : '',
$unfoldable ? ' data-group="' . $group . '"' : ''
);
if ( ! empty( $args['borders'] ) && in_array( 'top', $args['borders'], true ) ) {
$output .= '<div class="wpforms-panel-fields-group-border-top"></div>';
}
if ( ! empty( $args['title'] ) ) {
$chevron = $unfoldable ? '<i class="fa fa-chevron-circle-right"></i>' : '';
$output .= '<div class="wpforms-panel-fields-group-title">' . esc_html( $args['title'] ) . $chevron . '</div>';
}
if ( ! empty( $args['description'] ) ) {
$output .= '<div class="wpforms-panel-fields-group-description">' . wp_kses_post( $args['description'] ) . '</div>';
}
$output .= sprintf(
'<div class="wpforms-panel-fields-group-inner"%s>%s</div>',
empty( $opened ) && $unfoldable ? ' style="display: none;"' : '',
$inner
);
if ( ! empty( $args['borders'] ) && in_array( 'bottom', $args['borders'], true ) ) {
$output .= '<div class="wpforms-panel-fields-group-border-bottom"></div>';
}
$output .= '</div>';
if ( ! $echo ) {
return $output;
}
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
/**
* Get the pages for the "Show Page" dropdown selection in Confirmations Settings in Builder.
*
* @since 1.7.9
*
* @param array $form_data Form data.
* @param int $confirmation_id Confirmation ID.
*
* @return array
*/
function wpforms_builder_form_settings_confirmation_get_pages( $form_data, $confirmation_id ) {
$pre_selected_page_id = empty( $form_data['settings']['confirmations'][ $confirmation_id ]['page'] ) ? 0 : absint( $form_data['settings']['confirmations'][ $confirmation_id ]['page'] );
$pages = wp_list_pluck( wpforms_search_posts(), 'post_title', 'ID' );
if ( empty( $pre_selected_page_id ) || isset( $pages[ $pre_selected_page_id ] ) ) {
return $pages;
}
// If the pre-selected page isn't in `$pages`, we manually fetch it include it in `$pages`.
$pre_selected_page = get_post( $pre_selected_page_id );
if ( empty( $pre_selected_page ) ) {
return $pages;
}
$pages[ $pre_selected_page->ID ] = wpforms_get_post_title( $pre_selected_page );
return $pages;
}

View File

@@ -0,0 +1,300 @@
<?php
/**
* Base panel class.
*
* @since 1.0.0
*/
abstract class WPForms_Builder_Panel {
/**
* Full name of the panel.
*
* @since 1.0.0
*
* @var string
*/
public $name;
/**
* Slug.
*
* @since 1.0.0
*
* @var string
*/
public $slug;
/**
* Font Awesome Icon used for the editor button, eg "fa-list".
*
* @since 1.0.0
*
* @var mixed
*/
public $icon = false;
/**
* Priority order the field button should show inside the "Add Fields" tab.
*
* @since 1.0.0
*
* @var int
*/
public $order = 50;
/**
* If panel contains a sidebar element or is full width.
*
* @since 1.0.0
*
* @var bool
*/
public $sidebar = false;
/**
* Contain form object if we have one.
*
* @since 1.0.0
*
* @var object
*/
public $form;
/**
* Contain array of the form data (post_content).
*
* @since 1.0.0
*
* @var array
*/
public $form_data;
/**
* Class instance.
*
* @since 1.7.7
*
* @var static
*/
private static $instance;
/**
* Primary class constructor.
*
* @since 1.0.0
*/
public function __construct() {
// Load form if found.
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
$form_id = isset( $_GET['form_id'] ) ? absint( $_GET['form_id'] ) : false;
$this->form = wpforms()->get( 'form' )->get( $form_id );
$this->form_data = $this->form ? wpforms_decode( $this->form->post_content ) : false;
// Get current revision, if available.
$revision = wpforms()->get( 'revisions' )->get_revision();
// If we're viewing a valid revision, replace the form data so the Form Builder shows correct state.
if ( $revision && isset( $revision->post_content ) ) {
$this->form_data = wpforms_decode( $revision->post_content );
}
// Bootstrap.
$this->init();
// Load panel specific enqueues.
add_action( 'admin_enqueue_scripts', [ $this, 'enqueues' ], 15 );
// Primary panel button.
add_action( 'wpforms_builder_panel_buttons', [ $this, 'button' ], $this->order, 2 );
// Output.
add_action( 'wpforms_builder_panels', [ $this, 'panel_output' ], $this->order, 2 );
// Save instance.
self::$instance = $this;
}
/**
* Get class instance.
*
* @since 1.7.7
*
* @return static
*/
public static function instance() {
if ( self::$instance === null || ! self::$instance instanceof static ) {
self::$instance = new static();
}
return self::$instance;
}
/**
* All systems go. Used by children.
*
* @since 1.0.0
*/
public function init() {
}
/**
* Enqueue assets for the builder. Used by children.
*
* @since 1.0.0
*/
public function enqueues() {
}
/**
* Primary panel button in the left panel navigation.
*
* @since 1.0.0
*
* @param mixed $form
* @param string $view
*/
public function button( $form, $view ) {
$active = $view === $this->slug ? 'active' : '';
?>
<button class="wpforms-panel-<?php echo esc_attr( $this->slug ); ?>-button <?php echo $active; ?>" data-panel="<?php echo esc_attr( $this->slug ); ?>">
<i class="fa <?php echo esc_attr( $this->icon ); ?>"></i>
<span><?php echo esc_html( $this->name ); ?></span>
</button>
<?php
}
/**
* Output the contents of the panel.
*
* @since 1.0.0
*
* @param object $form Current form object.
* @param string $view Active Form Builder view (panel).
*/
public function panel_output( $form, $view ) {
$wrap = $this->sidebar ? 'wpforms-panel-sidebar-content' : 'wpforms-panel-full-content';
$classes = [ 'wpforms-panel' ];
if ( in_array( $this->slug, [ 'fields', 'revisions' ], true ) ) {
$classes[] = 'wpforms-panel-fields';
}
if ( $view === $this->slug ) {
$classes[] = 'active';
}
printf( '<div class="%s" id="wpforms-panel-%s">', wpforms_sanitize_classes( $classes, true ), esc_attr( $this->slug ) );
printf( '<div class="%s">', $wrap );
if ( true === $this->sidebar ) {
if ( $this->slug === 'fields' ) {
echo '<div class="wpforms-panel-sidebar-toggle"><div class="wpforms-panel-sidebar-toggle-vertical-line"></div><div class="wpforms-panel-sidebar-toggle-icon"><i class="fa fa-angle-left"></i></div></div>';
}
echo '<div class="wpforms-panel-sidebar">';
do_action( 'wpforms_builder_before_panel_sidebar', $this->form, $this->slug );
$this->panel_sidebar();
do_action( 'wpforms_builder_after_panel_sidebar', $this->form, $this->slug );
echo '</div>';
}
echo '<div class="wpforms-panel-content-wrap">';
echo '<div class="wpforms-panel-content">';
do_action( 'wpforms_builder_before_panel_content', $this->form, $this->slug );
$this->panel_content();
do_action( 'wpforms_builder_after_panel_content', $this->form, $this->slug );
echo '</div>';
echo '</div>';
echo '</div>';
echo '</div>';
}
/**
* Output the panel's sidebar if we have one.
*
* @since 1.0.0
*/
public function panel_sidebar() {
}
/**
* Output panel sidebar sections.
*
* @since 1.0.0
*
* @param string $name Sidebar section name.
* @param string $slug Sidebar section slug.
* @param string $icon Sidebar section icon.
*/
public function panel_sidebar_section( $name, $slug, $icon = '' ) {
$default_classes = [
'wpforms-panel-sidebar-section',
'wpforms-panel-sidebar-section-' . $slug,
];
if ( $slug === 'default' ) {
$default_classes[] = 'default';
}
if ( ! empty( $icon ) ) {
$default_classes[] = 'icon';
}
/**
* Allow adding custom CSS classes to a sidebar section in the Form Builder.
*
* @since 1.7.7.2
*
* @param array $classes Sidebar section classes.
* @param string $name Sidebar section name.
* @param string $slug Sidebar section slug.
* @param string $icon Sidebar section icon.
*/
$classes = (array) apply_filters( 'wpforms_builder_panel_sidebar_section_classes', [], $name, $slug, $icon );
$classes = array_merge( $default_classes, $classes );
echo '<a href="#" class="' . wpforms_sanitize_classes( $classes, true ) . '" data-section="' . esc_attr( $slug ) . '">';
if ( ! empty( $icon ) ) {
echo '<img src="' . esc_url( $icon ) . '">';
}
echo esc_html( $name );
echo '<i class="fa fa-angle-right wpforms-toggle-arrow"></i>';
echo '</a>';
}
/**
* Output the panel's primary content.
*
* @since 1.0.0
*/
public function panel_content() {
}
}

View File

@@ -0,0 +1,716 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Fields management panel.
*
* @since 1.0.0
*/
class WPForms_Builder_Panel_Fields extends WPForms_Builder_Panel {
/**
* All systems go.
*
* @since 1.0.0
*/
public function init() {
// Define panel information.
$this->name = esc_html__( 'Fields', 'wpforms-lite' );
$this->slug = 'fields';
$this->icon = 'fa-list-alt';
$this->order = 10;
$this->sidebar = true;
if ( $this->form ) {
add_action( 'wpforms_builder_fields', [ $this, 'search' ], 5 );
add_action( 'wpforms_builder_fields', [ $this, 'fields' ] );
add_action( 'wpforms_builder_fields_options', [ $this, 'fields_options' ] );
add_action( 'wpforms_builder_preview', [ $this, 'preview' ] );
// Template for form builder previews.
add_action( 'wpforms_builder_print_footer_scripts', [ $this, 'field_preview_templates' ] );
add_action( 'wpforms_builder_print_footer_scripts', [ $this, 'choices_limit_message_template' ] );
add_action( 'wpforms_builder_print_footer_scripts', [ $this, 'choices_empty_message_template' ] );
}
}
/**
* Enqueue assets for the Fields panel.
*
* @since 1.0.0
* @since 1.6.8 All the builder stylesheets enqueues moved to the `\WPForms_Builder::enqueues()`.
*/
public function enqueues() {
$min = wpforms_get_min_suffix();
wp_enqueue_script(
'wpforms-builder-drag-fields',
WPFORMS_PLUGIN_URL . "assets/js/components/admin/builder/drag-fields{$min}.js",
[ 'wpforms-builder' ],
WPFORMS_VERSION,
true
);
wp_enqueue_script(
'wpforms-builder-search-fields',
WPFORMS_PLUGIN_URL . "assets/js/components/admin/builder/search-fields{$min}.js",
[ 'wpforms-builder' ],
WPFORMS_VERSION,
true
);
}
/**
* Output the Field panel sidebar.
*
* @since 1.0.0
*/
public function panel_sidebar() {
// Sidebar contents are not valid unless we have a form.
if ( ! $this->form ) {
return;
}
?>
<ul class="wpforms-tabs wpforms-clear">
<li class="wpforms-tab" id="add-fields">
<a href="#" class="active">
<i class="fa fa-list-alt"></i><?php esc_html_e( 'Add Fields', 'wpforms-lite' ); ?>
</a>
</li>
<li class="wpforms-tab" id="field-options">
<a href="#">
<i class="fa fa-sliders"></i><?php esc_html_e( 'Field Options', 'wpforms-lite' ); ?>
</a>
</li>
</ul>
<div class="wpforms-add-fields wpforms-tab-content">
<?php do_action( 'wpforms_builder_fields', $this->form ); ?>
</div>
<div id="wpforms-field-options" class="wpforms-field-options wpforms-tab-content">
<?php do_action( 'wpforms_builder_fields_options', $this->form ); ?>
</div>
<?php
}
/**
* Output the Field panel primary content.
*
* @since 1.0.0
*/
public function panel_content() {
// Check if there is a form created.
if ( ! $this->form ) {
echo '<div class="wpforms-alert wpforms-alert-info">';
echo wp_kses(
__( 'You need to <a href="#" class="wpforms-panel-switch" data-panel="setup">setup your form</a> before you can manage the fields.', 'wpforms-lite' ),
[
'a' => [
'href' => [],
'class' => [],
'data-panel' => [],
],
]
);
echo '</div>';
return;
}
?>
<div class="wpforms-preview-wrap">
<div class="wpforms-preview">
<div class="wpforms-title-desc">
<div class="wpforms-title-desc-inner">
<h2 class="wpforms-form-name">
<?php echo esc_html( isset( $this->form_data['settings']['form_title'] ) ? $this->form_data['settings']['form_title'] : $this->form->post_title ); ?>
</h2>
<span class="wpforms-form-desc">
<?php
echo wp_kses(
isset( $this->form_data['settings']['form_desc'] ) ? $this->form_data['settings']['form_desc'] : $this->form->post_excerpt,
wpforms_builder_preview_get_allowed_tags()
);
?>
</span>
</div>
</div>
<div class="wpforms-no-fields-holder wpforms-hidden">
<?php $this->no_fields_options(); ?>
<?php $this->no_fields_preview(); ?>
</div>
<div class="wpforms-field-wrap">
<?php do_action( 'wpforms_builder_preview', $this->form ); ?>
</div>
<?php
$captcha_settings = wpforms_get_captcha_settings();
$extra_class = 'is-' . $captcha_settings['provider'];
?>
<div class="wpforms-field-recaptcha <?php echo sanitize_html_class( $extra_class ); ?>">
<div class="wpforms-field-recaptcha-wrap">
<div class="wpforms-field-recaptcha-wrap-l">
<svg class="wpforms-field-hcaptcha-icon" fill="none" viewBox="0 0 83 90"><path opacity=".5" d="M60.012 69.998H50.01V80h10.002V69.998z" fill="#0074BF"/><path opacity=".7" d="M50.01 69.998H40.008V80H50.01V69.998zM40.008 69.998H30.006V80h10.002V69.998z" fill="#0074BF"/><path opacity=".5" d="M30.006 69.998H20.004V80h10.002V69.998z" fill="#0074BF"/><path opacity=".7" d="M70.014 60.013H60.014v10.002h10.002V60.012z" fill="#0082BF"/><path opacity=".8" d="M60.012 60.013H50.01v10.002h10.002V60.012z" fill="#0082BF"/><path d="M50.01 60.013H40.008v10.002H50.01V60.012zM40.008 60.013H30.006v10.002h10.002V60.012z" fill="#0082BF"/><path opacity=".8" d="M30.006 60.013H20.004v10.002h10.002V60.012z" fill="#0082BF"/><path opacity=".7" d="M20.004 60.013H10.002v10.002h10.002V60.012z" fill="#0082BF"/><path opacity=".5" d="M80 50.01H69.998v10.002H80V50.01z" fill="#008FBF"/><path opacity=".8" d="M70.014 50.01H60.014v10.002h10.002V50.01z" fill="#008FBF"/><path d="M60.012 50.01H50.01v10.002h10.002V50.01zM50.01 50.01H40.008v10.002H50.01V50.01zM40.008 50.01H30.006v10.002h10.002V50.01zM30.006 50.01H20.004v10.002h10.002V50.01z" fill="#008FBF"/><path opacity=".8" d="M20.004 50.01H10.002v10.002h10.002V50.01z" fill="#008FBF"/><path opacity=".5" d="M10.002 50.01H0v10.002h10.002V50.01z" fill="#008FBF"/><path opacity=".7" d="M80 40.008H69.998V50.01H80V40.008z" fill="#009DBF"/><path d="M70.014 40.008H60.014V50.01h10.002V40.008zM60.012 40.008H50.01V50.01h10.002V40.008zM50.01 40.008H40.008V50.01H50.01V40.008zM40.008 40.008H30.006V50.01h10.002V40.008zM30.006 40.008H20.004V50.01h10.002V40.008zM20.004 40.008H10.002V50.01h10.002V40.008z" fill="#009DBF"/><path opacity=".7" d="M10.002 40.008H0V50.01h10.002V40.008z" fill="#009DBF"/><path opacity=".7" d="M80 30.006H69.998v10.002H80V30.006z" fill="#00ABBF"/><path d="M70.014 30.006H60.014v10.002h10.002V30.006zM60.012 30.006H50.01v10.002h10.002V30.006zM50.01 30.006H40.008v10.002H50.01V30.006zM40.008 30.006H30.006v10.002h10.002V30.006zM30.006 30.006H20.004v10.002h10.002V30.006zM20.004 30.006H10.002v10.002h10.002V30.006z" fill="#00ABBF"/><path opacity=".7" d="M10.002 30.006H0v10.002h10.002V30.006z" fill="#00ABBF"/><path opacity=".5" d="M80 20.004H69.998v10.002H80V20.004z" fill="#00B9BF"/><path opacity=".8" d="M70.014 20.004H60.014v10.002h10.002V20.004z" fill="#00B9BF"/><path d="M60.012 20.004H50.01v10.002h10.002V20.004zM50.01 20.004H40.008v10.002H50.01V20.004zM40.008 20.004H30.006v10.002h10.002V20.004zM30.006 20.004H20.004v10.002h10.002V20.004z" fill="#00B9BF"/><path opacity=".8" d="M20.004 20.004H10.002v10.002h10.002V20.004z" fill="#00B9BF"/><path opacity=".5" d="M10.002 20.004H0v10.002h10.002V20.004z" fill="#00B9BF"/><path opacity=".7" d="M70.014 10.002H60.014v10.002h10.002V10.002z" fill="#00C6BF"/><path opacity=".8" d="M60.012 10.002H50.01v10.002h10.002V10.002z" fill="#00C6BF"/><path d="M50.01 10.002H40.008v10.002H50.01V10.002zM40.008 10.002H30.006v10.002h10.002V10.002z" fill="#00C6BF"/><path opacity=".8" d="M30.006 10.002H20.004v10.002h10.002V10.002z" fill="#00C6BF"/><path opacity=".7" d="M20.004 10.002H10.002v10.002h10.002V10.002z" fill="#00C6BF"/><path opacity=".5" d="M60.012 0H50.01v10.002h10.002V0z" fill="#00D4BF"/><path opacity=".7" d="M50.01 0H40.008v10.002H50.01V0zM40.008 0H30.006v10.002h10.002V0z" fill="#00D4BF"/><path opacity=".5" d="M30.006 0H20.004v10.002h10.002V0z" fill="#00D4BF"/><path d="M26.34 36.84l2.787-6.237c1.012-1.592.88-3.55-.232-4.66a3.6 3.6 0 00-.481-.399 3.053 3.053 0 00-2.571-.298 4.246 4.246 0 00-2.322 1.791s-3.816 8.907-5.242 12.905c-1.426 3.998-.863 11.346 4.611 16.836 5.806 5.806 14.215 7.132 19.573 3.102.232-.116.431-.25.63-.415l16.521-13.8c.797-.664 1.99-2.024.93-3.583-1.046-1.526-3.003-.481-3.816.033l-9.504 6.917a.421.421 0 01-.597-.05s0-.017-.017-.017c-.249-.298-.282-1.078.1-1.393l14.58-12.374c1.26-1.128 1.426-2.787.414-3.915-.995-1.11-2.57-1.078-3.848.067l-13.12 10.267a.578.578 0 01-.813-.083c0-.016-.017-.016-.017-.033-.265-.298-.365-.78-.066-1.078l14.862-14.414c1.178-1.095 1.244-2.936.15-4.097a2.824 2.824 0 00-2.024-.863 2.905 2.905 0 00-2.09.83L39.544 36.144c-.365.364-1.078 0-1.161-.432a.474.474 0 01.132-.431l11.628-13.237a2.86 2.86 0 00.15-4.047 2.86 2.86 0 00-4.048-.15c-.05.05-.1.084-.133.133L28.447 37.47c-.63.63-1.56.664-2.007.299a.657.657 0 01-.1-.929z" fill="#fff"/></svg>
<svg class="wpforms-field-recaptcha-icon" viewBox="0 0 28 27.918"><path d="M28 13.943l-.016-.607V2l-3.133 3.134a13.983 13.983 0 00-21.964.394l5.134 5.183a6.766 6.766 0 012.083-2.329A6.171 6.171 0 0114.025 7.1a1.778 1.778 0 01.492.066 6.719 6.719 0 015.17 3.119l-3.625 3.641 11.941.016" fill="#1c3aa9"/><path d="M13.943 0l-.607.016H2.018l3.133 3.133a13.969 13.969 0 00.377 21.964l5.183-5.134A6.766 6.766 0 018.382 17.9 6.171 6.171 0 017.1 13.975a1.778 1.778 0 01.066-.492 6.719 6.719 0 013.117-5.167l3.641 3.641L13.943 0" fill="#4285f4"/><path d="M0 13.975l.016.607v11.334l3.133-3.133a13.983 13.983 0 0021.964-.394l-5.134-5.183a6.766 6.766 0 01-2.079 2.33 6.171 6.171 0 01-3.92 1.279 1.778 1.778 0 01-.492-.066 6.719 6.719 0 01-5.167-3.117l3.641-3.641c-4.626 0-9.825.016-11.958-.016" fill="#ababab"/></svg>
<svg class="wpforms-field-turnstile-icon" fill="none" viewBox="0 0 106 106"> <g clip-path="url(#a)"> <path fill="#F4801F" d="m72.375 76.265.541-1.877c.643-2.231.405-4.29-.678-5.808-1.011-1.397-2.66-2.216-4.68-2.312l-38.213-.486a.743.743 0 0 1-.683-1.012 1.012 1.012 0 0 1 .885-.678l38.583-.506c4.554-.207 9.532-3.92 11.267-8.454l2.196-5.748a1.354 1.354 0 0 0 .061-.779 25.13 25.13 0 0 0-48.312-2.6 11.307 11.307 0 0 0-17.708 11.849A16.054 16.054 0 0 0 .172 76.28a.744.744 0 0 0 .734.643H71.48a.927.927 0 0 0 .895-.658Z"/> <path fill="#F9AB41" d="M85.11 49.82c-.338 0-.692.01-1.063.03a.444.444 0 0 0-.162.035.59.59 0 0 0-.384.405l-1.518 5.191c-.648 2.231-.41 4.29.678 5.808a5.895 5.895 0 0 0 4.675 2.313l8.15.505a.728.728 0 0 1 .577.314.759.759 0 0 1 .086.693 1.012 1.012 0 0 1-.885.678l-8.465.506c-4.599.213-9.552 3.921-11.287 8.45l-.612 1.598a.455.455 0 0 0 .4.617h29.157a.782.782 0 0 0 .779-.592 20.92 20.92 0 0 0-10.822-24.36 20.916 20.916 0 0 0-9.294-2.191h-.01Z"/> </g> <defs> <clipPath id="a"> <path fill="#fff" d="M0 0h106v106H0z"/> </clipPath> </defs> </svg>
</div>
<div class="wpforms-field-recaptcha-wrap-r">
<p class="wpforms-field-hcaptcha-title">hCaptcha</p>
<p class="wpforms-field-recaptcha-title">reCAPTCHA</p>
<p class="wpforms-field-turnstile-title">Turnstile</p>
<p class="wpforms-field-recaptcha-desc">
<span class="wpforms-field-recaptcha-desc-txt"><?php esc_html_e( 'Enabled', 'wpforms-lite' ); ?></span><svg class="wpforms-field-recaptcha-desc-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M512 256c0-37.7-23.7-69.9-57.1-82.4 14.7-32.4 8.8-71.9-17.9-98.6-26.7-26.7-66.2-32.6-98.6-17.9C325.9 23.7 293.7 0 256 0s-69.9 23.7-82.4 57.1c-32.4-14.7-72-8.8-98.6 17.9-26.7 26.7-32.6 66.2-17.9 98.6C23.7 186.1 0 218.3 0 256s23.7 69.9 57.1 82.4c-14.7 32.4-8.8 72 17.9 98.6 26.6 26.6 66.1 32.7 98.6 17.9 12.5 33.3 44.7 57.1 82.4 57.1s69.9-23.7 82.4-57.1c32.6 14.8 72 8.7 98.6-17.9 26.7-26.7 32.6-66.2 17.9-98.6 33.4-12.5 57.1-44.7 57.1-82.4zm-144.8-44.25L236.16 341.74c-4.31 4.28-11.28 4.25-15.55-.06l-75.72-76.33c-4.28-4.31-4.25-11.28.06-15.56l26.03-25.82c4.31-4.28 11.28-4.25 15.56.06l42.15 42.49 97.2-96.42c4.31-4.28 11.28-4.25 15.55.06l25.82 26.03c4.28 4.32 4.26 11.29-.06 15.56z"></path></svg>
</p>
</div>
</div>
</div>
<?php
$submit = ! empty( $this->form_data['settings']['submit_text'] ) ? $this->form_data['settings']['submit_text'] : esc_html__( 'Submit', 'wpforms-lite' );
$submit_style = empty( $this->form_data['fields'] ) ? 'display: none;' : '';
printf( '<p class="wpforms-field-submit" style="%1$s"><input type="submit" value="%2$s" class="wpforms-field-submit-button"></p>', esc_attr( $submit_style ), esc_attr( $submit ) );
/** This action is documented in includes/class-frontend.php. */
do_action( 'wpforms_display_submit_after', $this->form_data, 'submit' ); // phpcs:ignore WPForms.PHP.ValidateHooks.InvalidHookName
?>
<?php wpforms_debug_data( $this->form_data ); ?>
</div>
</div>
<?php
}
/**
* Builder field buttons.
*
* @since 1.0.0
*/
public function fields() {
$fields = wpforms_get_builder_fields();
// Output the buttons.
foreach ( $fields as $id => $group ) {
usort( $group['fields'], [ $this, 'field_order' ] );
echo '<div class="wpforms-add-fields-group">';
echo '<a href="#" class="wpforms-add-fields-heading" data-group="' . esc_attr( $id ) . '">';
echo '<span>' . esc_html( $group['group_name'] ) . '</span>';
echo '<i class="fa fa-angle-down"></i>';
echo '</a>';
echo '<div class="wpforms-add-fields-buttons">';
foreach ( $group['fields'] as $field ) {
/**
* Attributes of the form field button on the Add Fields tab in the Form Builder.
*
* @since 1.5.1
*
* @param array $attributes Field attributes.
* @param array $field Field data.
* @param array $form_data Form data.
*/
$atts = apply_filters(
'wpforms_builder_field_button_attributes',
[
'id' => 'wpforms-add-fields-' . $field['type'],
'class' => [ 'wpforms-add-fields-button' ],
'data' => [
'field-type' => $field['type'],
],
'atts' => [],
],
$field,
$this->form_data
);
if ( ! empty( $field['keywords'] ) ) {
$atts['data']['field-keywords'] = $field['keywords'];
}
if ( ! empty( $field['class'] ) ) {
$atts['class'][] = $field['class'];
}
echo '<button ' . wpforms_html_attributes( $atts['id'], $atts['class'], $atts['data'], $atts['atts'] ) . '>';
if ( $field['icon'] ) {
echo '<i class="fa ' . esc_attr( $field['icon'] ) . '"></i> ';
}
echo esc_html( $field['name'] );
echo '</button>';
}
echo '</div>';
echo '</div>';
}
}
/**
* Editor Field Options.
*
* @since 1.0.0
*/
public function fields_options() {
// Check to make sure the form actually has fields created already.
if ( empty( $this->form_data['fields'] ) ) {
$this->no_fields_options();
return;
}
$fields = $this->form_data['fields'];
foreach ( $fields as $field ) {
$class = apply_filters( 'wpforms_builder_field_option_class', '', $field );
printf( '<div class="wpforms-field-option wpforms-field-option-%s %s" id="wpforms-field-option-%d" data-field-id="%d">', sanitize_html_class( $field['type'] ), wpforms_sanitize_classes( $class ), (int) $field['id'], (int) $field['id'] );
printf( '<input type="hidden" name="fields[%d][id]" value="%d" class="wpforms-field-option-hidden-id">', (int) $field['id'], (int) $field['id'] );
printf( '<input type="hidden" name="fields[%d][type]" value="%s" class="wpforms-field-option-hidden-type">', (int) $field['id'], esc_attr( $field['type'] ) );
do_action( "wpforms_builder_fields_options_{$field['type']}", $field );
echo '</div>';
}
}
/**
* Editor preview (right pane).
*
* @since 1.0.0
*/
public function preview() {
// Check to make sure the form actually has fields created already.
if ( empty( $this->form_data['fields'] ) ) {
$this->no_fields_preview();
return;
}
/**
* Filters the fields which must be displayed on the base level on the preview panel in the Form Builder.
*
* @since 1.7.7
*
* @param array $fields Form fields data.
*/
$fields = (array) apply_filters( 'wpforms_builder_panel_fields_preview_fields', $this->form_data['fields'] );
foreach ( $fields as $field ) {
$this->preview_single_field(
$field,
[]
);
}
}
/**
* Preview single field.
*
* @since 1.7.7
*
* @param array $field Field data.
* @param array $args Additional arguments.
*/
public function preview_single_field( $field, $args ) {
$class = ! empty( $field['size'] ) ? 'size-' . esc_attr( $field['size'] ) : '';
$class .= ! empty( $field['label_hide'] ) ? ' label_hide' : '';
$class .= isset( $field['label'] ) && empty( $field['label'] ) && $field['type'] !== 'html' ? ' label_empty' : '';
$class .= ! empty( $field['sublabel_hide'] ) ? ' sublabel_hide' : '';
$class .= ! empty( $field['required'] ) ? ' required' : '';
$class .= isset( $field['meta']['delete'] ) && $field['meta']['delete'] === false ? ' no-delete' : '';
$class .= isset( $field['meta']['duplicate'] ) && $field['meta']['duplicate'] === false ? ' no-duplicate' : '';
if ( ! empty( $field['input_columns'] ) ) {
$class .= $field['input_columns'] === '2' ? ' wpforms-list-2-columns' : '';
$class .= $field['input_columns'] === '3' ? ' wpforms-list-3-columns' : '';
$class .= $field['input_columns'] === 'inline' ? ' wpforms-list-inline' : '';
}
/**
* Filters class attribute of the field preview container in the Form Builder.
*
* @since 1.4.0
*
* @param string $css Field preview class.
* @param array $field Field data.
*/
$class = apply_filters( 'wpforms_field_preview_class', $class, $field ); // phpcs:ignore WPForms.PHP.ValidateHooks.InvalidHookName
if ( ! has_action( "wpforms_display_field_{$field['type']}" ) ) {
$this->unavailable_fields_preview( $field );
return;
}
printf(
'<div class="wpforms-field wpforms-field-%1$s %2$s" id="wpforms-field-%3$d" data-field-id="%3$d" data-field-type="%1$s">',
esc_attr( $field['type'] ),
esc_attr( $class ),
absint( $field['id'] )
);
/**
* Filters display field duplicate button flag.
*
* @since 1.5.6.2
*
* @param bool $display_duplicate_button Display field duplicate button flag.
* @param array $field Field data.
* @param array $form_data Form data.
*/
if ( apply_filters( 'wpforms_field_preview_display_duplicate_button', true, $field, $this->form_data ) ) { // phpcs:ignore WPForms.PHP.ValidateHooks.InvalidHookName
printf(
'<a href="#" class="wpforms-field-duplicate" title="%s"><i class="fa fa-files-o" aria-hidden="true"></i></a>',
esc_attr__( 'Duplicate Field', 'wpforms-lite' )
);
}
printf(
'<a href="#" class="wpforms-field-delete" title="%s"><i class="fa fa-trash-o" aria-hidden="true"></i></a>',
esc_attr__( 'Delete Field', 'wpforms-lite' )
);
if ( empty( $_COOKIE['wpforms_field_helper_hide'] ) ) {
printf(
'<div class="wpforms-field-helper">
<span class="wpforms-field-helper-edit">%s</span>
<span class="wpforms-field-helper-drag">%s</span>
<span class="wpforms-field-helper-hide" title="%s">
<i class="fa fa-times-circle" aria-hidden="true"></i>
</span>
</div>',
esc_html__( 'Click to Edit', 'wpforms-lite' ),
esc_html__( 'Drag to Reorder', 'wpforms-lite' ),
esc_attr__( 'Hide Helper', 'wpforms-lite' )
);
}
/**
* Fires after the field preview output in the Form Builder.
*
* @since 1.0.0
*
* @param array $field Field data.
*/
do_action( "wpforms_builder_fields_previews_{$field['type']}", $field ); // phpcs:ignore WPForms.PHP.ValidateHooks.InvalidHookName
echo '</div>';
}
/**
* Generate HTML for hidden inputs from given data.
*
* @since 1.6.7
*
* @param array $data Field array data.
* @param string $name Input name prefix.
*/
private function generate_hidden_inputs( $data = [], $name = '' ) {
if ( ! is_array( $data ) || empty( $data ) ) {
return;
}
foreach ( $data as $key => $value ) {
if ( $key === 'id' ) {
continue;
}
$key = ! empty( $data['id'] ) ? sprintf( '[%s][%s]', $data['id'], $key ) : sprintf( '[%s]', $key );
if ( ! empty( $name ) ) {
$key = trim( $name ) . $key;
}
if ( is_array( $value ) ) {
$this->generate_hidden_inputs( $value, $key );
} else {
printf( "<input type='hidden' name='%s' value='%s' />", esc_attr( $key ), esc_attr( $value ) );
}
}
}
/**
* Unavailable builder field display.
*
* @since 1.6.7
*
* @param array $field Field array data.
*/
public function unavailable_fields_preview( $field ) {
// Using ucwords() for certain fields may generate incorrect words.
switch ( $field['type'] ) {
case 'url':
$field_type = 'URL';
break;
case 'html':
$field_type = 'HTML';
break;
case 'gdpr-checkbox':
$field_type = 'GDPR Checkbox';
break;
default:
$field_type = ucwords( preg_replace( '/[_-]/', ' ', $field['type'] ) );
}
$warning_message = sprintf( /* translators: %s - unavailable field name. */
esc_html__( 'Unfortunately, the %s field is not available and will be ignored on the front end.', 'wpforms-lite' ),
'<b>' . $field_type . '</b>'
);
$field_id = isset( $field['id'] ) ? $field['id'] : 0;
printf(
'<div class="wpforms-alert wpforms-alert-warning wpforms-alert-dismissible wpforms-alert-field-not-available" data-field-id="%d" data-field-type="unavailable">',
absint( $field_id )
);
printf(
'<div class="wpforms-alert-message">
<p>%1$s</p>
</div>
<div class="wpforms-alert-buttons">
<a href="%2$s" target="_blank" rel="noopener noreferrer" class="wpforms-btn wpforms-btn-md wpforms-btn-light-grey">%3$s</a>
<button type="button" class="wpforms-dismiss-button" title="%4$s" data-field-id="%5$d" />
</div>',
$warning_message, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
'https://wpforms.com/docs/how-to-import-and-export-wpforms/#field-missing',
esc_html__( 'Learn More', 'wpforms-lite' ),
esc_attr__( 'Dismiss this message. The field will be deleted as well.', 'wpforms-lite' ),
absint( $field_id )
);
// Save unavailable fields data in hidden inputs.
$this->generate_hidden_inputs( $field, 'fields' );
echo '</div>';
}
/**
* No fields options markup.
*
* @since 1.6.0
*/
public function no_fields_options() {
printf(
'<p class="no-fields wpforms-alert wpforms-alert-warning">%s</p>',
esc_html__( 'You don\'t have any fields yet.', 'wpforms-lite' )
);
}
/**
* No fields preview placeholder markup.
*
* @since 1.6.0
*/
public function no_fields_preview() {
printf(
'<div class="no-fields-preview">
<h4>%1$s</h4>
<p>%2$s</p>
</div>',
esc_html__( 'You don\'t have any fields yet. Add some!', 'wpforms-lite' ),
esc_html__( 'Take your pick from our wide variety of fields and start building out your form!', 'wpforms-lite' )
);
}
/**
* Sort Add Field buttons by order provided.
*
* @since 1.0.0
*
* @param array $a First item.
* @param array $b Second item.
*
* @return array
*/
public function field_order( $a, $b ) {
return $a['order'] - $b['order'];
}
/**
* Template for form builder preview.
*
* @since 1.4.5
*/
public function field_preview_templates() {
// Checkbox, Radio, and Payment Multiple/Checkbox field choices.
?>
<script type="text/html" id="tmpl-wpforms-field-preview-checkbox-radio-payment-multiple">
<# if ( data.settings.choices_images ) { #>
<ul class="primary-input wpforms-image-choices wpforms-image-choices-{{ data.settings.choices_images_style }}">
<# _.each( data.order, function( choiceID, key ) { #>
<li class="wpforms-image-choices-item<# if ( 1 === data.settings.choices[choiceID].default ) { print( ' wpforms-selected' ); } #>">
<label>
<span class="wpforms-image-choices-image">
<# if ( ! _.isEmpty( data.settings.choices[choiceID].image ) ) { #>
<img src="{{ data.settings.choices[choiceID].image }}" alt="{{ data.settings.choices[choiceID].label }}" title="{{ data.settings.choices[choiceID].label }}">
<# } else { #>
<img src="{{ wpforms_builder.image_placeholder }}" alt="{{ data.settings.choices[choiceID].label }}" title="{{ data.settings.choices[choiceID].label }}">
<# } #>
</span>
<# if ( 'none' === data.settings.choices_images_style ) { #>
<br>
<input type="{{ data.type }}" readonly<# if ( 1 === data.settings.choices[choiceID].default ) { print( ' checked' ); } #>>
<# } else { #>
<input class="wpforms-screen-reader-element" type="{{ data.type }}" readonly<# if ( 1 === data.settings.choices[choiceID].default ) { print( ' checked' ); } #>>
<# } #>
<span class="wpforms-image-choices-label">
{{{ WPFormsBuilder.fieldChoiceLabel( data, choiceID ) }}}
</span>
</label>
</li>
<# }) #>
</ul>
<# } else if ( data.settings.choices_icons ) { #>
<ul class='primary-input wpforms-icon-choices wpforms-icon-choices-{{ data.settings.choices_icons_style }} wpforms-icon-choices-{{ data.settings.choices_icons_size }}' style="--wpforms-icon-choices-color: {{ data.settings.choices_icons_color }};">
<# _.each( data.order, function( choiceID, key ) { #>
<li class="wpforms-icon-choices-item<# if ( 1 === data.settings.choices[choiceID].default ) { print( ' wpforms-selected' ); } #>">
<label>
<span class="wpforms-icon-choices-icon">
<i class="ic-fa-{{ data.settings.choices[choiceID].icon_style }} ic-fa-{{ data.settings.choices[choiceID].icon }}"></i>
<span class="wpforms-icon-choices-icon-bg"></span>
</span>
<# if ( 'none' === data.settings.choices_icons_style ) { #>
<input type='{{ data.type }}' readonly<# if ( 1 === data.settings.choices[choiceID].default ) { print( ' checked' ); } #>>
<# } else { #>
<input class='wpforms-screen-reader-element' type='{{ data.type }}' readonly<# if ( 1 === data.settings.choices[choiceID].default ) { print( ' checked' ); } #>>
<# } #>
<span class='wpforms-icon-choices-label'>
{{{ WPFormsBuilder.fieldChoiceLabel( data, choiceID ) }}}
</span>
</label>
</li>
<# }) #>
</ul>
<# } else { #>
<ul class="primary-input">
<# _.each( data.order, function( choiceID, key ) { #>
<li>
<input type="{{ data.type }}" readonly<# if ( 1 === data.settings.choices[choiceID].default ) { print( ' checked' ); } #>>
{{{ WPFormsBuilder.fieldChoiceLabel( data, choiceID ) }}}
</li>
<# }) #>
</ul>
<# } #>
</script>
<?php
}
/**
* Template for form builder preview.
*
* @since 1.6.9
*/
public function choices_limit_message_template() {
?>
<script type="text/html" id="tmpl-wpforms-choices-limit-message">
<div class="wpforms-alert-dynamic wpforms-alert wpforms-alert-warning">
<?php
printf(
wp_kses( /* translators: %s - total amount of choices. */
__( 'Showing the first 20 choices.<br> All %s choices will be displayed when viewing the form.', 'wpforms-lite' ),
[
'br' => [],
]
),
'{{ data.total }}'
);
?>
</div>
</script>
<?php
}
/**
* Template for empty choices message.
*
* @since 1.8.2
*
* @return void
*/
public function choices_empty_message_template() {
?>
<script type="text/html" id="tmpl-wpforms-empty-choice-message">
<div class="wpforms-notice-dynamic-empty wpforms-alert wpforms-alert-warning">
{{ data.message }}
</div>
</script>
<?php
}
/**
* Builder fields search.
*
* @since 1.8.3
*/
public function search() {
?>
<div class="wpforms-search-fields-wrapper">
<div class="wpforms-search-fields-input-wrapper">
<label for="wpforms-search-fields-input" class="wpforms-screen-reader-element"><?php esc_html_e( 'Search fields:', 'wpforms-lite' ); ?></label>
<input type="search" id="wpforms-search-fields-input" placeholder="<?php echo esc_attr__( 'Search fields...', 'wpforms-lite' ); ?>" autocomplete="off">
<i class="fa fa-times wpforms-search-fields-input-close" aria-hidden="true"></i>
</div>
<div class="wpforms-search-fields-list">
<div class="wpforms-add-fields-group">
<div class="wpforms-add-fields-buttons"></div>
</div>
</div>
<div class="wpforms-search-fields-no-results">
<p>
<?php esc_html_e( 'Sorry, we didn\'t find any fields that match your criteria.', 'wpforms-lite' ); ?>
</p>
</div>
</div>
<?php
}
}
new WPForms_Builder_Panel_Fields();

View File

@@ -0,0 +1,112 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Payments panel.
*
* @since 1.0.0
*/
class WPForms_Builder_Panel_Payments extends WPForms_Builder_Panel {
/**
* All systems go.
*
* @since 1.0.0
*/
public function init() {
// Define panel information.
$this->name = esc_html__( 'Payments', 'wpforms-lite' );
$this->slug = 'payments';
$this->icon = 'fa-usd';
$this->order = 10;
$this->sidebar = true;
}
/**
* Output the Payments panel sidebar.
*
* @since 1.0.0
*/
public function panel_sidebar() {
// Sidebar contents are not valid unless we have a form.
if ( ! $this->form ) {
return;
}
$this->panel_sidebar_section( esc_html__( 'Default', 'wpforms-lite' ), 'default' );
do_action( 'wpforms_payments_panel_sidebar', $this->form );
}
/**
* Output the Payments panel primary content.
*
* @since 1.0.0
*/
public function panel_content() {
// An array of all the active provider addons.
$payments_active = apply_filters( 'wpforms_payments_available', [] );
if ( ! $this->form ) {
// Check if there is a form created. When no form has been created
// yet let the user know we need a form to setup a payment.
echo '<div class="wpforms-alert wpforms-alert-info">';
echo wp_kses(
__( 'You need to <a href="#" class="wpforms-panel-switch" data-panel="setup">setup your form</a> before you can manage these settings.', 'wpforms-lite' ),
[
'a' => [
'href' => [],
'class' => [],
'data-panel' => [],
],
]
);
echo '</div>';
return;
}
if ( empty( $payments_active ) ) {
// Check for active payment addons. When no payment addons are
// activated let the user know they need to install/activate an
// addon to setup a payment.
echo '<div class="wpforms-panel-content-section wpforms-panel-content-section-default">
<div class="illustration illustration-payments"></div>
<h5>' . esc_html__( 'Install Your Payment Integration', 'wpforms-lite' ) . '</h5>
<p>' . sprintf(
wp_kses(
/* translators: %s - addons page URL. */
__( 'It seems you do not have any payment addons activated. You can head over to the <a href="%s">Addons page</a> to install and activate the addon for your payment service.', 'wpforms-lite' ),
[
'a' => [
'href' => [],
],
]
),
esc_url( admin_url( 'admin.php?page=wpforms-addons' ) )
) .
'</p>
</div>';
} else {
// Everything is good - display default instructions.
echo '<div class="wpforms-panel-content-section wpforms-panel-content-section-default">
<div class="illustration illustration-payments"></div>
<h5>' . esc_html__( 'Install Your Payment Integration', 'wpforms-lite' ) . '</h5>
<p>' . esc_html__( 'It seems you don\'t have any payment addons activated. Click one of the available addons and start accepting payments today!', 'wpforms-lite' ) . '</p>
</div>';
}
do_action( 'wpforms_payments_panel_content', $this->form );
}
}
new WPForms_Builder_Panel_Payments();

View File

@@ -0,0 +1,146 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Providers panel.
*
* @since 1.0.0
*/
class WPForms_Builder_Panel_Providers extends WPForms_Builder_Panel {
/**
* All systems go.
*
* @since 1.0.0
*/
public function init() {
// Define panel information.
$this->name = esc_html__( 'Marketing', 'wpforms-lite' );
$this->slug = 'providers';
$this->icon = 'fa-bullhorn';
$this->order = 10;
$this->sidebar = true;
}
/**
* Enqueue assets for the Providers panel.
*
* @since 1.0.0
* @since 1.6.8 All the builder stylesheets enqueues moved to the `\WPForms_Builder::enqueues()`.
*/
public function enqueues() {
$min = wpforms_get_min_suffix();
wp_enqueue_script(
'wpforms-builder-providers',
WPFORMS_PLUGIN_URL . "assets/js/admin-builder-providers{$min}.js",
[ 'jquery' ],
WPFORMS_VERSION,
false
);
wp_localize_script(
'wpforms-builder-providers',
'wpforms_builder_providers',
[
'url' => esc_url( remove_query_arg( 'newform', add_query_arg( [ 'view' => 'providers' ] ) ) ),
'confirm_save' => esc_html__( 'We need to save your progress to continue to the Marketing panel. Is that OK?', 'wpforms-lite' ),
'confirm_connection' => esc_html__( 'Are you sure you want to delete this connection?', 'wpforms-lite' ),
/* translators: %s - connection type. */
'prompt_connection' => esc_html( sprintf( __( 'Enter a %s nickname', 'wpforms-lite' ), '%type%' ) ),
'prompt_placeholder' => esc_html__( 'Eg: Newsletter Optin', 'wpforms-lite' ),
'error_name' => esc_html__( 'You must provide a connection nickname.', 'wpforms-lite' ),
'required_field' => esc_html__( 'Field required', 'wpforms-lite' ),
]
);
}
/**
* Output the Provider panel sidebar.
*
* @since 1.0.0
*/
public function panel_sidebar() {
// Sidebar contents are not valid unless we have a form.
if ( ! $this->form ) {
return;
}
$this->panel_sidebar_section( esc_html__( 'Default', 'wpforms-lite' ), 'default' );
do_action( 'wpforms_providers_panel_sidebar', $this->form );
}
/**
* Output the Provider panel primary content.
*
* @since 1.0.0
*/
public function panel_content() {
if ( ! $this->form ) {
// Check if there is a form created. When no form has been created
// yet let the user know we need a form to setup a provider.
echo '<div class="wpforms-alert wpforms-alert-info">';
echo wp_kses(
__( 'You need to <a href="#" class="wpforms-panel-switch" data-panel="setup">setup your form</a> before you can manage these settings.', 'wpforms-lite' ),
[
'a' => [
'href' => [],
'class' => [],
'data-panel' => [],
],
]
);
echo '</div>';
return;
}
// An array of all the active provider addons.
$providers_active = wpforms_get_providers_available();
if ( empty( $providers_active ) ) {
// Check for active provider addons. When no provider addons are
// activated let the user know they need to install/activate an
// addon to setup a provider.
echo '<div class="wpforms-panel-content-section wpforms-panel-content-section-info">';
echo '<h5>' . esc_html__( 'Install Your Marketing Integration', 'wpforms-lite' ) . '</h5>';
echo '<p>' .
sprintf(
wp_kses(
/* translators: %s - plugin admin area Addons page. */
__( 'It seems you do not have any marketing addons activated. You can head over to the <a href="%s">Addons page</a> to install and activate the addon for your provider.', 'wpforms-lite' ),
[
'a' => [
'href' => [],
],
]
),
esc_url( admin_url( 'admin.php?page=wpforms-addons' ) )
) .
'</p>';
echo '</div>';
} else {
// Everything is good - display default instructions.
echo '<div class="wpforms-panel-content-section wpforms-panel-content-section-default">
<div class="illustration illustration-marketing"></div>
<h5>' . esc_html__( 'Select Your Marketing Integration', 'wpforms-lite' ) . '</h5>
<p>' . esc_html__( 'Select your email marketing service provider or CRM from the options on the left. If you don\'t see your email marketing service listed, then let us know and we\'ll do our best to get it added as fast as possible.', 'wpforms-lite' ) . '</p>
</div>';
}
do_action( 'wpforms_providers_panel_content', $this->form );
}
}
new WPForms_Builder_Panel_Providers();

View File

@@ -0,0 +1,192 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Revisions management panel.
*
* @since 1.7.3
*/
class WPForms_Builder_Panel_Revisions extends WPForms_Builder_Panel {
/**
* All systems go.
*
* @since 1.7.3
*/
public function init() {
// Define panel information.
$this->name = esc_html__( 'Revisions', 'wpforms-lite' );
$this->slug = 'revisions';
$this->icon = 'fa-history';
$this->order = 10;
$this->sidebar = true;
$this->hooks();
}
/**
* Hook into WordPress lifecycle.
*
* @since 1.7.3
*/
private function hooks() {
// Add a notice above all panels if revision is loaded.
add_action( 'wpforms_builder_panels', [ $this, 'panel_notice' ], 100, 2 );
}
/**
* Primary panel button in the left panel navigation.
*
* @since 1.7.3
*
* @param mixed $form The form object.
* @param string $view Current view/panel.
*/
public function button( $form, $view ) {
$classes = 'wpforms-panel-revisions-button';
if ( $view === $this->slug ) {
$classes .= ' active';
}
$badge = '';
if ( $this->form && ! wp_revisions_enabled( $this->form ) && ! wpforms()->get( 'revisions' )->panel_viewed() ) {
$badge = '
<span class="badge-exclamation">
<svg width="4" height="10" fill="none">
<path fill="#fff" fill-rule="evenodd" d="M3.5 8.1c0-.8-.7-1.5-1.5-1.5S.5 7.3.5 8.1 1.2 9.6 2 9.6 3.5 8.9 3.5 8ZM1 .9c-.3 0-.5.2-.4.4l.2 4.4c0 .2.2.3.4.3h1.6c.2 0 .3-.1.4-.3l.2-4.4c0-.2-.2-.4-.4-.4H1Z" clip-rule="evenodd"/>
</svg>
</span>';
}
printf(
'<div class="wpforms-panel-revisions-button-spacer"></div>
<button class="%1$s" data-panel="%2$s" title="%6$s">
%3$s
<i class="fa %4$s"></i>
<span class="screen-reader-text">%5$s</span>
</button>',
esc_attr( $classes ),
esc_attr( $this->slug ),
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
$badge,
esc_attr( $this->icon ),
esc_html( $this->name ),
esc_html__( 'Form Revisions', 'wpforms-lite' )
);
}
/**
* Output the Settings panel sidebar.
*
* @since 1.7.3
*/
public function panel_sidebar() {
// Sidebar contents are not valid unless we have a form.
if ( ! $this->form ) {
return;
}
printf(
'<div class="wpforms-revisions-header">
<h3>%s</h3>
<p>%s</p>
</div>',
esc_html__( 'Form Revisions', 'wpforms-lite' ),
esc_html__( 'Select a revision to roll back to that version. All changes, including settings, will be reverted.', 'wpforms-lite' )
);
// Render a list of form revisions, including current version. All data is safe, escaped in the template.
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo wpforms()->get( 'revisions' )->render_revisions_list();
$revisions_to_keep = wp_revisions_to_keep( $this->form );
if ( $revisions_to_keep === 0 ) {
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo wpforms_render( 'builder/revisions/notice-disabled' );
}
if ( $revisions_to_keep > 0 ) {
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo wpforms_render(
'builder/revisions/notice-limited',
[
'revisions_to_keep' => $revisions_to_keep,
],
true
);
}
}
/**
* Output revision notice above the panels.
*
* @since 1.7.3
*
* @return void
*/
public function panel_notice() {
$revision = wpforms()->get( 'revisions' )->get_revision();
if ( ! $revision ) {
return;
}
$restore_link = sprintf(
'<a href="%1$s">%2$s</a>',
esc_url(
wp_nonce_url(
wpforms()->get( 'revisions' )->get_url(
[
'revision_id' => $revision->ID,
'action' => 'restore_revision',
]
),
'restore_revision',
'wpforms_nonce'
)
),
__( 'Restore this revision', 'wpforms-lite' )
);
$back_link = sprintf(
'<a href="%1$s">%2$s</a>',
esc_url( wpforms()->get( 'revisions' )->get_url() ),
__( 'go back to the current version', 'wpforms-lite' )
);
$message = sprintf( /* translators: %1$s - revision date, %2$s - revision time, %3$s - "Restore this revision" link, %4$s - "go back to the current version" link. */
__( 'Youre currently viewing a form revision from %1$s at %2$s. %3$s or %4$s.', 'wpforms-lite' ),
wpforms()->get( 'revisions' )->get_formatted_datetime( $revision->post_modified_gmt ),
wpforms()->get( 'revisions' )->get_formatted_datetime( $revision->post_modified_gmt, 'time' ),
$restore_link,
$back_link
);
printf(
'<div class="wpforms-revision-notice">
<p><i class="fa fa-history"></i>%s</p>
</div>',
wp_kses(
$message,
[
'a' => [
'href' => [],
],
]
)
);
}
}
new WPForms_Builder_Panel_Revisions();

View File

@@ -0,0 +1,313 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
use WPForms\Admin\Forms\Tags;
use WPForms\Forms\Akismet;
/**
* Settings management panel.
*
* @since 1.0.0
*/
class WPForms_Builder_Panel_Settings extends WPForms_Builder_Panel {
/**
* All systems go.
*
* @since 1.0.0
*/
public function init() {
// Define panel information.
$this->name = esc_html__( 'Settings', 'wpforms-lite' );
$this->slug = 'settings';
$this->icon = 'fa-sliders';
$this->order = 10;
$this->sidebar = true;
}
/**
* Output the Settings panel sidebar.
*
* @since 1.0.0
*/
public function panel_sidebar() {
// Sidebar contents are not valid unless we have a form.
if ( ! $this->form ) {
return;
}
$sections = [
'general' => esc_html__( 'General', 'wpforms-lite' ),
'anti_spam' => esc_html__( 'Spam Protection and Security', 'wpforms-lite' ),
'notifications' => esc_html__( 'Notifications', 'wpforms-lite' ),
'confirmation' => esc_html__( 'Confirmations', 'wpforms-lite' ),
];
$sections = apply_filters( 'wpforms_builder_settings_sections', $sections, $this->form_data );
foreach ( $sections as $slug => $section ) {
$this->panel_sidebar_section( $section, $slug );
}
}
/**
* Enqueue assets.
*
* @since 1.7.5
*/
public function enqueues() {
$min = wpforms_get_min_suffix();
wp_enqueue_script(
'wpforms-builder-settings',
WPFORMS_PLUGIN_URL . "assets/js/components/admin/builder/settings{$min}.js",
[ 'wpforms-builder' ],
WPFORMS_VERSION,
true
);
wp_localize_script(
'wpforms-builder-settings',
'wpforms_builder_settings',
[
'choicesjs_config' => $this->get_choicesjs_config(),
'all_tags_choices' => Tags::get_all_tags_choices(),
]
);
}
/**
* Get Choices.js configuration.
*
* @since 1.7.5
*
* @return array
*/
private function get_choicesjs_config() {
$config = Tags::get_choicesjs_config();
$config['noResultsText'] = esc_html__( 'Press Enter or "," key to add new tag', 'wpforms-lite' );
return $config;
}
/**
* Output the Settings panel primary content.
*
* @since 1.0.0
*/
public function panel_content() {
// Check if there is a form created.
if ( ! $this->form ) {
echo '<div class="wpforms-alert wpforms-alert-info">';
echo wp_kses(
__( 'You need to <a href="#" class="wpforms-panel-switch" data-panel="setup">setup your form</a> before you can manage the settings.', 'wpforms-lite' ),
[
'a' => [
'href' => [],
'class' => [],
'data-panel' => [],
],
]
);
echo '</div>';
return;
}
/*
* General.
*/
echo '<div class="wpforms-panel-content-section wpforms-panel-content-section-general">';
echo '<div class="wpforms-panel-content-section-title">';
esc_html_e( 'General', 'wpforms-lite' );
echo '</div>';
wpforms_panel_field(
'text',
'settings',
'form_title',
$this->form_data,
esc_html__( 'Form Name', 'wpforms-lite' ),
[
'default' => $this->form->post_title,
]
);
wpforms_panel_field(
'textarea',
'settings',
'form_desc',
$this->form_data,
esc_html__( 'Form Description', 'wpforms-lite' )
);
$this->general_setting_tags();
wpforms_panel_field(
'text',
'settings',
'submit_text',
$this->form_data,
esc_html__( 'Submit Button Text', 'wpforms-lite' ),
[
'default' => esc_html__( 'Submit', 'wpforms-lite' ),
]
);
wpforms_panel_field(
'text',
'settings',
'submit_text_processing',
$this->form_data,
esc_html__( 'Submit Button Processing Text', 'wpforms-lite' ),
[
'tooltip' => esc_html__( 'Enter the submit button text you would like the button display while the form submit is processing.', 'wpforms-lite' ),
]
);
$this->general_setting_advanced();
echo '</div>';
/*
* Notifications.
*/
echo '<div class="wpforms-panel-content-section wpforms-panel-content-section-notifications" data-panel="notifications">';
do_action( 'wpforms_form_settings_notifications', $this );
echo '</div>';
/*
* Confirmations.
*/
echo '<div class="wpforms-panel-content-section wpforms-panel-content-section-confirmation" data-panel="confirmations">';
do_action( 'wpforms_form_settings_confirmations', $this );
echo '</div>';
/*
* Custom panels can be added below.
*/
do_action( 'wpforms_form_settings_panel_content', $this );
}
/**
* Output the Tags setting.
*
* @since 1.7.5
*/
private function general_setting_tags() {
$form_tags = [];
if ( ! empty( $this->form_data['settings']['form_tags'] ) ) {
$form_tags = get_terms(
[
'taxonomy' => WPForms_Form_Handler::TAGS_TAXONOMY,
'name' => $this->form_data['settings']['form_tags'],
'hide_empty' => false,
]
);
$form_tags = is_wp_error( $form_tags ) ? [] : (array) $form_tags;
}
$tags_value = wp_list_pluck( $form_tags, 'term_id' );
$tags_options = wp_list_pluck( $form_tags, 'name', 'term_id' );
wpforms_panel_field(
'select',
'settings',
'form_tags',
$this->form_data,
esc_html__( 'Tags', 'wpforms-lite' ),
[
'options' => $tags_options,
'value' => $tags_value,
'multiple' => true,
'tooltip' => esc_html__( 'Mark form with the tags. To create a new tag, simply type it and press Enter.', 'wpforms-lite' ),
]
);
}
/**
* Output the *CAPTCHA settings.
*
* @since 1.6.8
*/
private function general_setting_advanced() {
ob_start();
wpforms_panel_field(
'text',
'settings',
'form_class',
$this->form_data,
esc_html__( 'Form CSS Class', 'wpforms-lite' ),
[
'tooltip' => esc_html__( 'Enter CSS class names for the form wrapper. Multiple class names should be separated with spaces.', 'wpforms-lite' ),
]
);
wpforms_panel_field(
'text',
'settings',
'submit_class',
$this->form_data,
esc_html__( 'Submit Button CSS Class', 'wpforms-lite' ),
[
'tooltip' => esc_html__( 'Enter CSS class names for the form submit button. Multiple names should be separated with spaces.', 'wpforms-lite' ),
]
);
wpforms_panel_field(
'toggle',
'settings',
'dynamic_population',
$this->form_data,
esc_html__( 'Enable Prefill by URL', 'wpforms-lite' ),
[
'tooltip' => sprintf(
'<a href="%1$s" target="_blank" rel="noopener noreferrer">%2$s</a>',
wpforms_utm_link( 'https://wpforms.com/developers/how-to-enable-dynamic-field-population/', 'Builder Settings', 'Prefill by URL Tooltip' ),
esc_html__( 'How to use Prefill by URL', 'wpforms-lite' )
),
]
);
wpforms_panel_field(
'toggle',
'settings',
'ajax_submit',
$this->form_data,
esc_html__( 'Enable AJAX form submission', 'wpforms-lite' ),
[
'tooltip' => esc_html__( 'Enables form submission without page reload.', 'wpforms-lite' ),
]
);
do_action( 'wpforms_form_settings_general', $this );
// Wrap advanced settings to the unfoldable group.
wpforms_panel_fields_group(
ob_get_clean(),
[
'borders' => [ 'top' ],
'unfoldable' => true,
'group' => 'settings_advanced',
'title' => esc_html__( 'Advanced', 'wpforms-lite' ),
],
true
);
}
}
new WPForms_Builder_Panel_Settings();

View File

@@ -0,0 +1,103 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Setup panel.
*
* @since 1.0.0
* @since 1.6.8 Form Builder Refresh.
*/
class WPForms_Builder_Panel_Setup extends WPForms_Builder_Panel {
use \WPForms\Admin\Traits\FormTemplates;
/**
* All systems go.
*
* @since 1.0.0
*/
public function init() {
// Define panel information.
$this->name = esc_html__( 'Setup', 'wpforms-lite' );
$this->slug = 'setup';
$this->icon = 'fa-cog';
$this->order = 5;
$this->addons_obj = wpforms()->get( 'addons' );
}
/**
* Enqueue assets for the Setup panel.
*
* @since 1.0.0
* @since 1.6.8 All the builder stylesheets enqueues moved to the `\WPForms_Builder::enqueues()`.
*/
public function enqueues() {
$min = wpforms_get_min_suffix();
wp_enqueue_script(
'wpforms-builder-setup',
WPFORMS_PLUGIN_URL . "assets/js/components/admin/builder/setup{$min}.js",
[ 'wpforms-builder', 'listjs' ],
WPFORMS_VERSION,
true
);
}
/**
* Output the Settings panel primary content.
*
* @since 1.0.0
*/
public function panel_content() {
?>
<div id="wpforms-setup-form-name">
<label for="wpforms-setup-name"><?php esc_html_e( 'Name Your Form', 'wpforms-lite' ); ?></label>
<input type="text" id="wpforms-setup-name" placeholder="<?php esc_attr_e( 'Enter your form name here&hellip;', 'wpforms-lite' ); ?>">
</div>
<div class="wpforms-setup-title">
<?php esc_html_e( 'Select a Template', 'wpforms-lite' ); ?>
<span class="wpforms-setup-title-after"></span>
</div>
<p class="wpforms-setup-desc secondary-text">
<?php
printf(
wp_kses( /* translators: %1$s - create template doc link, %2$s - Contact us page link. */
__( 'To speed up the process you can select from one of our pre-made templates, start with a <a href="#" class="wpforms-trigger-blank">blank form</a> or <a href="%1$s" target="_blank" rel="noopener noreferrer">create your own</a>. Have a suggestion for a new template? <a href="%2$s" target="_blank" rel="noopener noreferrer">Wed love to hear it</a>!', 'wpforms-lite' ),
[
'strong' => [],
'a' => [
'href' => [],
'class' => [],
'target' => [],
'rel' => [],
],
]
),
esc_url( wpforms_utm_link( 'https://wpforms.com/docs/how-to-create-a-custom-form-template/', 'builder-templates', 'Create Your Own Template Documentation' ) ),
esc_url( wpforms_utm_link( 'https://wpforms.com/form-template-suggestion/', 'builder-templates', 'Suggest a Template' ) )
);
?>
</p>
<?php
$this->output_templates_content();
/**
* Fires after WPForms builder setup panel.
*
* @since 1.0.6
*/
do_action( 'wpforms_setup_panel_after' ); // phpcs:ignore WPForms.PHP.ValidateHooks.InvalidHookName
}
}
new WPForms_Builder_Panel_Setup();

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,383 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Functionality related to the admin TinyMCE editor.
*
* @since 1.0.0
*/
class WPForms_Admin_Editor {
/**
* Primary class constructor.
*
* @since 1.0.0
*/
public function __construct() {
add_action( 'media_buttons', [ $this, 'media_button' ], 15 );
}
/**
* Allow easy shortcode insertion via a custom media button.
*
* @since 1.0.0
*
* @param string $editor_id Editor Id.
*/
public function media_button( $editor_id ) {
if ( ! \wpforms_current_user_can( 'view_forms' ) ) {
return;
}
// Provide the ability to conditionally disable the button, so it can be
// disabled for custom fields or front-end use such as bbPress. We default
// to only showing within the post editor page.
if ( ! apply_filters( 'wpforms_display_media_button', $this->is_post_editor_page(), $editor_id ) ) {
return;
}
// Setup the icon - currently using a dashicon.
$icon = '<span class="wp-media-buttons-icon wpforms-menu-icon" style="font-size:16px;margin-top:-2px;"><svg width="18" height="18" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M643 911v128h-252v-128h252zm0-255v127h-252v-127h252zm758 511v128h-341v-128h341zm0-256v128h-672v-128h672zm0-255v127h-672v-127h672zm135 860v-1240q0-8-6-14t-14-6h-32l-378 256-210-171-210 171-378-256h-32q-8 0-14 6t-6 14v1240q0 8 6 14t14 6h1240q8 0 14-6t6-14zm-855-1110l185-150h-406zm430 0l221-150h-406zm553-130v1240q0 62-43 105t-105 43h-1240q-62 0-105-43t-43-105v-1240q0-62 43-105t105-43h1240q62 0 105 43t43 105z" fill="#82878c"/></svg></span>';
printf(
'<a href="#" class="button wpforms-insert-form-button" data-editor="%s" title="%s">%s %s</a>',
esc_attr( $editor_id ),
esc_attr__( 'Add Form', 'wpforms-lite' ),
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
$icon,
esc_html__( 'Add Form', 'wpforms-lite' )
);
$min = wpforms_get_min_suffix();
// If we have made it this far then load the JS.
wp_enqueue_script(
'wpforms-editor',
WPFORMS_PLUGIN_URL . "assets/js/admin-editor{$min}.js",
[ 'jquery' ],
WPFORMS_VERSION,
true
);
add_action( 'admin_footer', [ $this, 'shortcode_modal' ] );
}
/**
* Check if we are on the post editor admin page.
*
* @since 1.6.2
*
* @returns boolean True if it is post editor admin page.
*/
public function is_post_editor_page() {
if ( ! is_admin() ) {
return false;
}
// get_current_screen() is loaded after 'admin_init' hook and may not exist yet.
if ( ! function_exists( 'get_current_screen' ) ) {
return false;
}
$screen = get_current_screen();
return $screen !== null && $screen->parent_base === 'edit';
}
/**
* Modal window for inserting the form shortcode into TinyMCE.
*
* Thickbox is old and busted so we don't use that. Creating a custom view in
* Backbone would make me pull my hair out. So instead we offer a small clean
* modal that is based off of the WordPress insert link modal.
*
* @since 1.0.0
*/
public function shortcode_modal() {
?>
<div id="wpforms-modal-backdrop" style="display: none"></div>
<div id="wpforms-modal-wrap" style="display: none">
<form id="wpforms-modal" tabindex="-1">
<div id="wpforms-modal-title">
<?php esc_html_e( 'Insert Form', 'wpforms-lite' ); ?>
<button type="button" id="wpforms-modal-close"><span class="screen-reader-text"><?php esc_html_e( 'Close', 'wpforms-lite' ); ?></span></button>
</div>
<div id="wpforms-modal-inner">
<div id="wpforms-modal-options">
<?php
echo '<p id="wpforms-modal-notice">';
printf(
wp_kses( /* translators: %s - WPForms documentation URL. */
__( 'Heads up! Don\'t forget to test your form. <a href="%s" target="_blank" rel="noopener noreferrer">Check out our complete guide</a>!', 'wpforms-lite' ),
[
'a' => [
'href' => [],
'rel' => [],
'target' => [],
],
]
),
'https://wpforms.com/docs/how-to-properly-test-your-wordpress-forms-before-launching-checklist/'
);
echo '</p>';
$args = apply_filters( 'wpforms_modal_select', [] );
$forms = wpforms()->form->get( '', $args );
if ( ! empty( $forms ) ) {
printf( '<p><label for="wpforms-modal-select-form">%s</label></p>', esc_html__( 'Select a form below to insert', 'wpforms-lite' ) );
echo '<select id="wpforms-modal-select-form">';
foreach ( $forms as $form ) {
printf( '<option value="%d">%s</option>', $form->ID, esc_html( $form->post_title ) );
}
echo '</select><br>';
printf( '<p class="wpforms-modal-inline"><input type="checkbox" id="wpforms-modal-checkbox-title"><label for="wpforms-modal-checkbox-title">%s</label></p>', esc_html__( 'Show form name', 'wpforms-lite' ) );
printf( '<p class="wpforms-modal-inline"><input type="checkbox" id="wpforms-modal-checkbox-description"><label for="wpforms-modal-checkbox-description">%s</label></p>', esc_html__( 'Show form description', 'wpforms-lite' ) );
} else {
echo '<p>';
printf(
wp_kses(
/* translators: %s - WPForms Builder page. */
__( 'Whoops, you haven\'t created a form yet. Want to <a href="%s">give it a go</a>?', 'wpforms-lite' ),
[
'a' => [
'href' => [],
],
]
),
admin_url( 'admin.php?page=wpforms-builder' )
);
echo '</p>';
}
?>
</div>
</div>
<div class="submitbox">
<div id="wpforms-modal-cancel">
<a class="submitdelete deletion" href="#"><?php esc_html_e( 'Cancel', 'wpforms-lite' ); ?></a>
</div>
<?php if ( ! empty( $forms ) ) : ?>
<div id="wpforms-modal-update">
<button class="button button-primary" id="wpforms-modal-submit"><?php esc_html_e( 'Add Form', 'wpforms-lite' ); ?></button>
</div>
<?php endif; ?>
</div>
</form>
</div>
<style type="text/css">
.wpforms-insert-form-button svg path {
fill: #0071a1;
}
.wpforms-insert-form-button:hover svg path {
fill: #016087;
}
#wpforms-modal-wrap {
display: none;
background-color: #fff;
-webkit-box-shadow: 0 3px 6px rgba(0, 0, 0, 0.3);
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.3);
width: 500px;
height: 285px;
overflow: hidden;
margin-left: -250px;
margin-top: -125px;
position: fixed;
top: 50%;
left: 50%;
z-index: 100205;
-webkit-transition: height 0.2s, margin-top 0.2s;
transition: height 0.2s, margin-top 0.2s;
}
#wpforms-modal-backdrop {
display: none;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
min-height: 360px;
background: #000;
opacity: 0.7;
filter: alpha(opacity=70);
z-index: 100200;
}
#wpforms-modal {
position: relative;
height: 100%;
}
#wpforms-modal-title {
background: #fcfcfc;
border-bottom: 1px solid #dfdfdf;
height: 36px;
font-size: 18px;
font-weight: 600;
line-height: 36px;
padding: 0 36px 0 16px;
top: 0;
right: 0;
left: 0;
}
#wpforms-modal-close {
color: #666;
padding: 0;
position: absolute;
top: 0;
right: 0;
width: 36px;
height: 36px;
text-align: center;
background: none;
border: none;
cursor: pointer;
}
#wpforms-modal-close:before {
font: normal 20px/36px 'dashicons';
vertical-align: top;
speak: none;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
width: 36px;
height: 36px;
content: '\f158';
}
#wpforms-modal-close:hover,
#wpforms-modal-close:focus {
color: #2ea2cc;
}
#wpforms-modal-close:focus {
outline: none;
-webkit-box-shadow: 0 0 0 1px #5b9dd9,
0 0 2px 1px rgba(30, 140, 190, .8);
box-shadow: 0 0 0 1px #5b9dd9,
0 0 2px 1px rgba(30, 140, 190, .8);
}
#wpforms-modal-inner {
padding: 0 16px 50px;
}
#wpforms-modal-search-toggle:after {
display: inline-block;
font: normal 20px/1 'dashicons';
vertical-align: top;
speak: none;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
content: '\f140';
}
#wpforms-modal-notice {
background-color: #d9edf7;
border: 1px solid #bce8f1;
color: #31708f;
padding: 10px;
}
#wpforms-modal #wpforms-modal-options {
padding: 8px 0 12px;
}
#wpforms-modal #wpforms-modal-options .wpforms-modal-inline {
display: inline-block;
margin: 0;
padding: 0 20px 0 0;
}
#wpforms-modal-select-form {
margin-bottom: 1em;
max-width: 100%;
}
#wpforms-modal .submitbox {
padding: 8px 16px;
background: #fcfcfc;
border-top: 1px solid #dfdfdf;
position: absolute;
bottom: 0;
left: 0;
right: 0;
}
#wpforms-modal-cancel {
line-height: 25px;
float: left;
}
#wpforms-modal-update {
line-height: 23px;
float: right;
}
#wpforms-modal-submit {
float: right;
margin-bottom: 0;
}
@media screen and ( max-width: 782px ) {
#wpforms-modal-wrap {
height: 280px;
margin-top: -140px;
}
#wpforms-modal-inner {
padding: 0 16px 60px;
}
#wpforms-modal-cancel {
line-height: 32px;
}
}
@media screen and ( max-width: 520px ) {
#wpforms-modal-wrap {
width: auto;
margin-left: 0;
left: 10px;
right: 10px;
max-width: 500px;
}
}
@media screen and ( max-height: 520px ) {
#wpforms-modal-wrap {
-webkit-transition: none;
transition: none;
}
}
@media screen and ( max-height: 290px ) {
#wpforms-modal-wrap {
height: auto;
margin-top: 0;
top: 10px;
bottom: 10px;
}
#wpforms-modal-inner {
overflow: auto;
height: -webkit-calc(100% - 92px);
height: calc(100% - 92px);
padding-bottom: 2px;
}
}
</style>
<?php
}
}
new WPForms_Admin_Editor();

View File

@@ -0,0 +1,27 @@
<?php
use WPForms\Helpers\PluginSilentUpgraderSkin;
/**
* Skin for on-the-fly addon installations.
*
* @since 1.0.0
* @since 1.5.6.1 Extend PluginSilentUpgraderSkin and clean up the class.
*/
class WPForms_Install_Skin extends PluginSilentUpgraderSkin {
/**
* Instead of outputting HTML for errors, json_encode the errors and send them
* back to the Ajax script for processing.
*
* @since 1.0.0
*
* @param array $errors Array of errors with the install process.
*/
public function error( $errors ) {
if ( ! empty( $errors ) ) {
wp_send_json_error( $errors );
}
}
}

View File

@@ -0,0 +1,435 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Register menu elements and do other global tasks.
*
* @since 1.0.0
*/
class WPForms_Admin_Menu {
/**
* Primary class constructor.
*
* @since 1.0.0
*/
public function __construct() {
// Let's make some menus.
add_action( 'admin_menu', [ $this, 'register_menus' ], 9 );
add_action( 'admin_head', [ $this, 'hide_wpforms_submenu_items' ] );
add_action( 'admin_head', [ $this, 'adjust_pro_menu_item' ] );
add_action( 'admin_head', [ $this, 'admin_menu_styles' ], 11 );
// Plugins page settings link.
add_filter( 'plugin_action_links_' . plugin_basename( WPFORMS_PLUGIN_DIR . 'wpforms.php' ), [ $this, 'settings_link' ], 10, 4 );
}
/**
* Register our menus.
*
* @since 1.0.0
*/
public function register_menus() {
$manage_cap = wpforms_get_capability_manage_options();
$access = wpforms()->get( 'access' );
if ( ! method_exists( $access, 'get_menu_cap' ) ) {
return;
}
// Default Forms top level menu item.
add_menu_page(
esc_html__( 'WPForms', 'wpforms-lite' ),
esc_html__( 'WPForms', 'wpforms-lite' ),
$access->get_menu_cap( 'view_forms' ),
'wpforms-overview',
[ $this, 'admin_page' ],
'data:image/svg+xml;base64,' . base64_encode( '<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path fill="#9ea3a8" d="M643 911v128h-252v-128h252zm0-255v127h-252v-127h252zm758 511v128h-341v-128h341zm0-256v128h-672v-128h672zm0-255v127h-672v-127h672zm135 860v-1240q0-8-6-14t-14-6h-32l-378 256-210-171-210 171-378-256h-32q-8 0-14 6t-6 14v1240q0 8 6 14t14 6h1240q8 0 14-6t6-14zm-855-1110l185-150h-406zm430 0l221-150h-406zm553-130v1240q0 62-43 105t-105 43h-1240q-62 0-105-43t-43-105v-1240q0-62 43-105t105-43h1240q62 0 105 43t43 105z"/></svg>' ),
apply_filters( 'wpforms_menu_position', '58.9' )
);
// All Forms sub menu item.
add_submenu_page(
'wpforms-overview',
esc_html__( 'WPForms', 'wpforms-lite' ),
esc_html__( 'All Forms', 'wpforms-lite' ),
$access->get_menu_cap( 'view_forms' ),
'wpforms-overview',
[ $this, 'admin_page' ]
);
// Add New sub menu item.
add_submenu_page(
'wpforms-overview',
esc_html__( 'WPForms Builder', 'wpforms-lite' ),
esc_html__( 'Add New', 'wpforms-lite' ),
$access->get_menu_cap( [ 'create_forms', 'edit_forms' ] ),
'wpforms-builder',
[ $this, 'admin_page' ]
);
// Entries sub menu item.
add_submenu_page(
'wpforms-overview',
esc_html__( 'Form Entries', 'wpforms-lite' ),
esc_html__( 'Entries', 'wpforms-lite' ),
$access->get_menu_cap( 'view_entries' ),
'wpforms-entries',
[ $this, 'admin_page' ]
);
// Payments sub menu item.
add_submenu_page(
'wpforms-overview',
esc_html__( 'Payments', 'wpforms-lite' ),
esc_html__( 'Payments', 'wpforms-lite' ) . $this->get_new_badge_html(),
$manage_cap,
WPForms\Admin\Payments\Payments::SLUG,
[ $this, 'admin_page' ]
);
do_action_deprecated(
'wpform_admin_menu',
[ $this ],
'1.5.5 of the WPForms plugin',
'wpforms_admin_menu'
);
do_action( 'wpforms_admin_menu', $this );
// Templates sub menu item.
add_submenu_page(
'wpforms-overview',
esc_html__( 'WPForms Templates', 'wpforms-lite' ),
esc_html__( 'Form Templates', 'wpforms-lite' ),
$access->get_menu_cap( 'create_forms' ),
'wpforms-templates',
[ $this, 'admin_page' ]
);
// Settings sub menu item.
add_submenu_page(
'wpforms-overview',
esc_html__( 'WPForms Settings', 'wpforms-lite' ),
esc_html__( 'Settings', 'wpforms-lite' ),
$manage_cap,
'wpforms-settings',
[ $this, 'admin_page' ]
);
// Tools sub menu item.
add_submenu_page(
'wpforms-overview',
esc_html__( 'WPForms Tools', 'wpforms-lite' ),
esc_html__( 'Tools', 'wpforms-lite' ),
$access->get_menu_cap( [ 'create_forms', 'view_forms', 'view_entries' ] ),
'wpforms-tools',
[ $this, 'admin_page' ]
);
// Hidden placeholder paged used for misc content.
add_submenu_page(
'wpforms-settings',
esc_html__( 'WPForms', 'wpforms-lite' ),
esc_html__( 'Info', 'wpforms-lite' ),
$access->get_menu_cap( 'any' ),
'wpforms-page',
[ $this, 'admin_page' ]
);
// Addons submenu page.
add_submenu_page(
'wpforms-overview',
esc_html__( 'WPForms Addons', 'wpforms-lite' ),
'<span style="color:#f18500">' . esc_html__( 'Addons', 'wpforms-lite' ) . '</span>',
$manage_cap,
'wpforms-addons',
[ $this, 'admin_page' ]
);
// Analytics submenu page.
add_submenu_page(
'wpforms-overview',
esc_html__( 'Analytics', 'wpforms-lite' ),
esc_html__( 'Analytics', 'wpforms-lite' ),
$manage_cap,
WPForms\Admin\Pages\Analytics::SLUG,
[ $this, 'admin_page' ]
);
// SMTP submenu page.
add_submenu_page(
'wpforms-overview',
esc_html__( 'SMTP', 'wpforms-lite' ),
esc_html__( 'SMTP', 'wpforms-lite' ),
$manage_cap,
WPForms\Admin\Pages\SMTP::SLUG,
[ $this, 'admin_page' ]
);
// About submenu page.
add_submenu_page(
'wpforms-overview',
esc_html__( 'About WPForms', 'wpforms-lite' ),
esc_html__( 'About Us', 'wpforms-lite' ),
$access->get_menu_cap( 'any' ),
WPForms_About::SLUG,
[ $this, 'admin_page' ]
);
// Community submenu page.
add_submenu_page(
'wpforms-overview',
esc_html__( 'Community', 'wpforms-lite' ),
esc_html__( 'Community', 'wpforms-lite' ),
$manage_cap,
WPForms\Admin\Pages\Community::SLUG,
[ $this, 'admin_page' ]
);
if ( ! wpforms()->is_pro() ) {
add_submenu_page(
'wpforms-overview',
esc_html__( 'Upgrade to Pro', 'wpforms-lite' ),
esc_html__( 'Upgrade to Pro', 'wpforms-lite' ),
$manage_cap,
wpforms_admin_upgrade_link( 'admin-menu' )
);
}
}
/**
* Hide "Add New" admin menu item if a user can't create forms.
*
* @since 1.5.8
*/
public function hide_wpforms_submenu_items() {
if ( wpforms_current_user_can( 'create_forms' ) ) {
return;
}
global $submenu;
if ( ! isset( $submenu['wpforms-overview'] ) ) {
return;
}
foreach ( $submenu['wpforms-overview'] as $key => $item ) {
if ( isset( $item[2] ) && 'wpforms-builder' === $item[2] ) {
unset( $submenu['wpforms-overview'][ $key ] );
break;
}
}
$this->hide_wpforms_menu_item();
}
/**
* Hide "WPForms" admin menu if it has no submenu items.
*
* @since 1.5.8
*/
public function hide_wpforms_menu_item() {
global $submenu, $menu;
if ( ! empty( $submenu['wpforms-overview'] ) ) {
return;
}
unset( $submenu['wpforms-overview'] );
foreach ( $menu as $key => $item ) {
if ( isset( $item[2] ) && 'wpforms-overview' === $item[2] ) {
unset( $menu[ $key ] );
break;
}
}
}
/**
* Alias method for backward compatibility.
*
* @since 1.7.4
* @deprecated 1.7.8
*/
public function style_upgrade_pro_link() {
_deprecated_function( __METHOD__, '1.7.8 of the WPForms plugin', __CLASS__ . '::adjust_pro_menu_item()' );
$this->adjust_pro_menu_item();
}
/**
* Add the PRO badge to left sidebar menu item.
*
* @since 1.7.8
* @deprecated 1.8.1
*/
public function adjust_pro_menu_item_class() {
_deprecated_function( __METHOD__, '1.8.1 of the WPForms plugin', __CLASS__ . '::adjust_pro_menu_item()' );
$this->adjust_pro_menu_item();
}
/**
* Make changes to the PRO menu item.
*
* @since 1.8.1
*/
public function adjust_pro_menu_item() {
global $submenu;
// Bail if plugin menu is not registered.
if ( ! isset( $submenu['wpforms-overview'] ) ) {
return;
}
$upgrade_link_position = key(
array_filter(
$submenu['wpforms-overview'],
static function( $item ) {
return strpos( $item[2], 'https://wpforms.com/lite-upgrade' ) !== false;
}
)
);
// Bail if "Upgrade to Pro" menu item is not registered.
if ( $upgrade_link_position === null ) {
return;
}
// Add the PRO badge to the menu item.
// phpcs:disable WordPress.WP.GlobalVariablesOverride.Prohibited
if ( isset( $submenu['wpforms-overview'][ $upgrade_link_position ][4] ) ) {
$submenu['wpforms-overview'][ $upgrade_link_position ][4] .= ' wpforms-sidebar-upgrade-pro';
} else {
$submenu['wpforms-overview'][ $upgrade_link_position ][] = 'wpforms-sidebar-upgrade-pro';
}
$current_screen = get_current_screen();
$upgrade_utm_content = $current_screen === null ? 'Upgrade to Pro' : 'Upgrade to Pro - ' . $current_screen->base;
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
$upgrade_utm_content = empty( $_GET['view'] ) ? $upgrade_utm_content : $upgrade_utm_content . ': ' . sanitize_key( $_GET['view'] );
// Add utm_content to the menu item.
$submenu['wpforms-overview'][ $upgrade_link_position ][2] = esc_url(
add_query_arg(
'utm_content',
$upgrade_utm_content,
$submenu['wpforms-overview'][ $upgrade_link_position ][2]
)
);
// phpcs:enable WordPress.WP.GlobalVariablesOverride.Prohibited
}
/**
* Wrapper for the hook to render our custom settings pages.
*
* @since 1.0.0
*/
public function admin_page() {
do_action( 'wpforms_admin_page' );
}
/**
* Add settings link to the Plugins page.
*
* @since 1.3.9
*
* @param array $links Plugin row links.
* @param string $plugin_file Path to the plugin file relative to the plugins directory.
* @param array $plugin_data An array of plugin data. See `get_plugin_data()`.
* @param string $context The plugin context.
*
* @return array $links
*/
public function settings_link( $links, $plugin_file, $plugin_data, $context ) {
$custom['pro'] = sprintf(
'<a href="%1$s" aria-label="%2$s" target="_blank" rel="noopener noreferrer"
style="color: #00a32a; font-weight: 700;"
onmouseover="this.style.color=\'#008a20\';"
onmouseout="this.style.color=\'#00a32a\';"
>%3$s</a>',
esc_url(
wpforms_admin_upgrade_link(
'all-plugins',
'Get WPForms Pro'
)
),
esc_attr__( 'Upgrade to WPForms Pro', 'wpforms-lite' ),
esc_html__( 'Get WPForms Pro', 'wpforms-lite' )
);
$custom['settings'] = sprintf(
'<a href="%s" aria-label="%s">%s</a>',
esc_url(
add_query_arg(
[ 'page' => 'wpforms-settings' ],
admin_url( 'admin.php' )
)
),
esc_attr__( 'Go to WPForms Settings page', 'wpforms-lite' ),
esc_html__( 'Settings', 'wpforms-lite' )
);
$custom['docs'] = sprintf(
'<a href="%1$s" aria-label="%2$s" target="_blank" rel="noopener noreferrer">%3$s</a>',
esc_url(
add_query_arg(
[
'utm_content' => 'Documentation',
'utm_campaign' => 'liteplugin',
'utm_medium' => 'all-plugins',
'utm_source' => 'WordPress',
],
'https://wpforms.com/docs/'
)
),
esc_attr__( 'Read the documentation', 'wpforms-lite' ),
esc_html__( 'Docs', 'wpforms-lite' )
);
return array_merge( $custom, (array) $links );
}
/**
* Get the HTML for the "NEW!" badge.
*
* @since 1.7.8
*
* @return string
*/
private function get_new_badge_html() {
return '<span class="wpforms-menu-new">&nbsp;NEW!</span>';
}
/**
* Output inline styles for the admin menu.
*
* @since 1.7.8
*/
public function admin_menu_styles() {
$styles = '#adminmenu .wpforms-menu-new { color: #f18500; vertical-align: super; font-size: 9px; font-weight: 600; padding-left: 2px; }';
if ( ! wpforms()->is_pro() ) {
$styles .= 'a.wpforms-sidebar-upgrade-pro { background-color: #00a32a !important; color: #fff !important; font-weight: 600 !important; }';
}
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
printf( '<style>%s</style>', $styles );
}
}
new WPForms_Admin_Menu();

View File

@@ -0,0 +1,138 @@
<?php
/**
* Admin notices, on the fly.
*
* @example
* WPForms_Admin_Notice::success( 'All is good!' );
*
* @example
* WPForms_Admin_Notice::warning( 'Do something please.' );
*
* @since 1.3.9
* @deprecated 1.7.2
*/
class WPForms_Admin_Notice {
/**
* Single instance holder.
*
* @since 1.3.9
* @var mixed
*/
private static $_instance = null;
/**
* Added notices.
*
* @since 1.3.9
* @var array
*/
public $notices = [];
/**
* Get the instance.
*
* @since 1.3.9
* @return WPForms_Admin_Notice
*/
public static function getInstance() {
if ( self::$_instance === null ) {
self::$_instance = new WPForms_Admin_Notice();
}
return self::$_instance;
}
/**
* Hook when called.
*
* @since 1.3.9
*/
public function __construct() {
_deprecated_function( __METHOD__, '1.7.2 of the WPForms plugin' );
add_action( 'admin_notices', [ &$this, 'display' ] );
}
/**
* Display the notices.
*
* @since 1.3.9
*/
public function display() {
// At least one WPForms capability is needed to see admin notices.
if ( ! wpforms_current_user_can( 'any' ) ) {
return;
}
echo implode( ' ', $this->notices );
}
/**
* Add notice to instance property.
*
* @since 1.3.9
*
* @param string $message Message to display.
* @param string $type Type of the notice (default: '').
*/
public static function add( $message, $type = '' ) {
_deprecated_function( __METHOD__, '1.7.2 of the WPForms plugin' );
$instance = self::getInstance();
$id = 'wpforms-notice-' . ( count( $instance->notices ) + 1 );
$type = ! empty( $type ) ? 'notice-' . $type : '';
$notice = sprintf( '<div class="notice wpforms-notice %s" id="%s">%s</div>', $type, $id, wpautop( $message ) );
$instance->notices[] = $notice;
}
/**
* Add Info notice.
*
* @since 1.3.9
*
* @param string $message Message to display.
*/
public static function info( $message ) {
self::add( $message, 'info' );
}
/**
* Add Error notice.
*
* @since 1.3.9
*
* @param string $message Message to display.
*/
public static function error( $message ) {
self::add( $message, 'error' );
}
/**
* Add Success notice.
*
* @since 1.3.9
*
* @param string $message Message to display.
*/
public static function success( $message ) {
self::add( $message, 'success' );
}
/**
* Add Warning notice.
*
* @since 1.3.9
*
* @param string $message Message to display.
*/
public static function warning( $message ) {
self::add( $message, 'warning' );
}
}

View File

@@ -0,0 +1,320 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Ask for some love.
*
* @since 1.3.2
*/
class WPForms_Review {
/**
* Primary class constructor.
*
* @since 1.3.2
*/
public function __construct() {
// Admin notice requesting review.
add_action( 'admin_init', [ $this, 'review_request' ] );
add_action( 'wp_ajax_wpforms_review_dismiss', [ $this, 'review_dismiss' ] );
// Admin footer text.
add_filter( 'admin_footer_text', [ $this, 'admin_footer' ], 1, 2 );
add_action( 'in_admin_footer', [ $this, 'promote_wpforms' ] );
}
/**
* Add admin notices as needed for reviews.
*
* @since 1.3.2
*/
public function review_request() {
// Only consider showing the review request to admin users.
if ( ! is_super_admin() ) {
return;
}
// If the user has opted out of product announcement notifications, don't
// display the review request.
if ( wpforms_setting( 'hide-announcements', false ) ) {
return;
}
// Verify that we can do a check for reviews.
$notices = (array) get_option( 'wpforms_admin_notices', [] );
$time = time();
$load = false;
if ( empty( $notices['review_request'] ) ) {
$notices['review_request'] = [
'time' => $time,
'dismissed' => false,
];
update_option( 'wpforms_admin_notices', $notices );
return;
}
// Check if it has been dismissed or not.
if (
( isset( $notices['review_request']['dismissed'] ) &&
! $notices['review_request']['dismissed'] ) &&
(
isset( $notices['review_request']['time'] ) &&
( ( $notices['review_request']['time'] + DAY_IN_SECONDS ) <= $time )
)
) {
$load = true;
}
// If we cannot load, return early.
if ( ! $load ) {
return;
}
// Logic is slightly different depending on what's at our disposal.
if ( wpforms()->is_pro() && class_exists( 'WPForms_Entry_Handler', false ) ) {
$this->review();
} else {
$this->review_lite();
}
}
/**
* Maybe show review request.
*
* @since 1.3.9
*/
public function review() {
// Fetch total entries.
$entries = wpforms()->entry->get_entries( [ 'number' => 50 ], true );
// Only show review request if the site has collected at least 50 entries.
if ( empty( $entries ) || $entries < 50 ) {
return;
}
ob_start();
// We have a candidate! Output a review message.
?>
<p><?php esc_html_e( 'Hey, I noticed you collected over 50 entries from WPForms - thats awesome! Could you please do me a BIG favor and give it a 5-star rating on WordPress to help us spread the word and boost our motivation?', 'wpforms-lite' ); ?></p>
<p><strong><?php echo wp_kses( __( '~ Syed Balkhi<br>Co-Founder of WPForms', 'wpforms-lite' ), [ 'br' => [] ] ); ?></strong></p>
<p>
<a href="https://wordpress.org/support/plugin/wpforms-lite/reviews/?filter=5#new-post" class="wpforms-notice-dismiss wpforms-review-out" target="_blank" rel="noopener"><?php esc_html_e( 'Ok, you deserve it', 'wpforms-lite' ); ?></a><br>
<a href="#" class="wpforms-notice-dismiss" target="_blank" rel="noopener noreferrer"><?php esc_html_e( 'Nope, maybe later', 'wpforms-lite' ); ?></a><br>
<a href="#" class="wpforms-notice-dismiss" target="_blank" rel="noopener noreferrer"><?php esc_html_e( 'I already did', 'wpforms-lite' ); ?></a>
</p>
<?php
\WPForms\Admin\Notice::info(
ob_get_clean(),
[
'dismiss' => \WPForms\Admin\Notice::DISMISS_GLOBAL,
'slug' => 'review_request',
'autop' => false,
'class' => 'wpforms-review-notice',
]
);
}
/**
* Maybe show Lite review request.
*
* @since 1.3.9
*/
public function review_lite() {
// Fetch when plugin was initially installed.
$activated = get_option( 'wpforms_activated', [] );
if ( ! empty( $activated['lite'] ) ) {
// Only continue if plugin has been installed for at least 14 days.
if ( ( $activated['lite'] + ( DAY_IN_SECONDS * 14 ) ) > time() ) {
return;
}
} else {
$activated['lite'] = time();
update_option( 'wpforms_activated', $activated );
return;
}
// Only proceed with displaying if the user created at least one form.
$form_count = wp_count_posts( 'wpforms' );
if ( empty( $form_count->publish ) ) {
return;
}
// Check if the Constant Contact notice is displaying.
$cc = get_option( 'wpforms_constant_contact', false );
// If it's displaying don't ask for review until they configure CC or
// dismiss the notice.
if ( $cc ) {
return;
}
ob_start();
// We have a candidate! Output a review message.
?>
<p><?php esc_html_e( 'Hey, I noticed you created a contact form with WPForms - thats awesome! Could you please do me a BIG favor and give it a 5-star rating on WordPress to help us spread the word and boost our motivation?', 'wpforms-lite' ); ?></p>
<p><strong><?php echo wp_kses( __( '~ Syed Balkhi<br>Co-Founder of WPForms', 'wpforms-lite' ), [ 'br' => [] ] ); ?></strong></p>
<p>
<a href="https://wordpress.org/support/plugin/wpforms-lite/reviews/?filter=5#new-post" class="wpforms-notice-dismiss wpforms-review-out" target="_blank" rel="noopener noreferrer"><?php esc_html_e( 'Ok, you deserve it', 'wpforms-lite' ); ?></a><br>
<a href="#" class="wpforms-notice-dismiss" target="_blank" rel="noopener noreferrer"><?php esc_html_e( 'Nope, maybe later', 'wpforms-lite' ); ?></a><br>
<a href="#" class="wpforms-notice-dismiss" target="_blank" rel="noopener noreferrer"><?php esc_html_e( 'I already did', 'wpforms-lite' ); ?></a>
</p>
<?php
\WPForms\Admin\Notice::info(
ob_get_clean(),
[
'dismiss' => \WPForms\Admin\Notice::DISMISS_GLOBAL,
'slug' => 'review_lite_request',
'autop' => false,
'class' => 'wpforms-review-notice',
]
);
}
/**
* Dismiss the review admin notice.
*
* @deprecated 1.6.7.1
*
* @since 1.3.2
*/
public function review_dismiss() {
_deprecated_function( __METHOD__, '1.6.7.1 of the WPForms plugin' );
$review = get_option( 'wpforms_review', [] );
$review['time'] = time();
$review['dismissed'] = true;
update_option( 'wpforms_review', $review );
die;
}
/**
* When user is on a WPForms related admin page, display footer text
* that graciously asks them to rate us.
*
* @since 1.3.2
*
* @param string $text Footer text.
*
* @return string
*/
public function admin_footer( $text ) {
global $current_screen;
if ( ! empty( $current_screen->id ) && strpos( $current_screen->id, 'wpforms' ) !== false ) {
$url = 'https://wordpress.org/support/plugin/wpforms-lite/reviews/?filter=5#new-post';
$text = sprintf(
wp_kses( /* translators: $1$s - WPForms plugin name, $2$s - WP.org review link, $3$s - WP.org review link. */
__( 'Please rate %1$s <a href="%2$s" target="_blank" rel="noopener noreferrer">&#9733;&#9733;&#9733;&#9733;&#9733;</a> on <a href="%3$s" target="_blank" rel="noopener">WordPress.org</a> to help us spread the word.', 'wpforms-lite' ),
[
'a' => [
'href' => [],
'target' => [],
'rel' => [],
],
]
),
'<strong>WPForms</strong>',
$url,
$url
);
}
return $text;
}
/**
* Pre-footer promotion block, displayed on all WPForms admin pages except Form Builder.
*
* @since 1.8.0
*/
public function promote_wpforms() {
// Some 3rd-party addons may use page slugs that start with `wpforms-` (e.g. WPForms Views),
// so we should define exact pages we want the footer to be displayed on instead
// of targeting any page that looks like a WPForms page.
$plugin_pages = [
'wpforms-about',
'wpforms-addons',
'wpforms-analytics',
'wpforms-community',
'wpforms-entries',
'wpforms-overview',
'wpforms-payments',
'wpforms-settings',
'wpforms-smtp',
'wpforms-templates',
'wpforms-tools',
];
// phpcs:ignore WordPress.Security.NonceVerification
$current_page = isset( $_REQUEST['page'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['page'] ) ) : '';
if ( ! in_array( $current_page, $plugin_pages, true ) ) {
return;
}
$links = [
[
'url' => wpforms()->is_pro() ?
wpforms_utm_link(
'https://wpforms.com/account/support/',
'Plugin Footer',
'Contact Support'
) : 'https://wordpress.org/support/plugin/wpforms-lite/',
'text' => __( 'Support', 'wpforms-lite' ),
'target' => '_blank',
],
[
'url' => wpforms_utm_link(
'https://wpforms.com/docs/',
'Plugin Footer',
'Plugin Documentation'
),
'text' => __( 'Docs', 'wpforms-lite' ),
'target' => '_blank',
],
[
'url' => 'https://www.facebook.com/groups/wpformsvip/',
'text' => __( 'VIP Circle', 'wpforms-lite' ),
'target' => '_blank',
],
[
'url' => admin_url( 'admin.php?page=wpforms-about' ),
'text' => __( 'Free Plugins', 'wpforms-lite' ),
],
];
echo wpforms_render( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
'admin/promotion',
[
'title' => __( 'Made with ♥ by the WPForms Team', 'wpforms-lite' ),
'links' => $links,
],
true
);
}
}
new WPForms_Review();

View File

@@ -0,0 +1,753 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
use WPForms\Admin\Notice;
use WPForms\Migrations\Migrations as LiteMigration;
use WPForms\Pro\Migrations\Migrations;
/**
* Settings class.
*
* @since 1.0.0
*/
class WPForms_Settings {
/**
* The current active tab.
*
* @since 1.3.9
*
* @var string
*/
public $view;
/**
* Primary class constructor.
*
* @since 1.0.0
*/
public function __construct() {
$this->hooks();
}
/**
* Hooks.
*
* @since 1.8.5.4
*/
private function hooks() {
// Maybe load settings page.
add_action( 'admin_init', [ $this, 'init' ] );
}
/**
* Determine if the user is viewing the settings page, if so, party on.
*
* @since 1.0.0
*/
public function init() { // phpcs:ignore WPForms.PHP.HooksMethod.InvalidPlaceForAddingHooks
// Only load if we are actually on the settings page.
if ( ! wpforms_is_admin_page( 'settings' ) ) {
return;
}
// Include API callbacks and functions.
require_once WPFORMS_PLUGIN_DIR . 'includes/admin/settings-api.php';
// Show downgraded notice.
$this->maybe_display_downgraded_notice();
// Watch for triggered save.
$this->save_settings();
// Determine the current active settings tab.
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
$this->view = isset( $_GET['view'] ) ? sanitize_key( wp_unslash( $_GET['view'] ) ) : 'general';
$this->modify_url();
add_action( 'admin_enqueue_scripts', [ $this, 'enqueues' ] );
add_action( 'wpforms_admin_page', [ $this, 'output' ] );
// Monitor custom tables.
$this->monitor_custom_tables();
// Hook for addons.
do_action( 'wpforms_settings_init', $this );
}
/**
* Remove `wpforms-integration` query arg from URL.
* The `wpforms-integration` query arg is used to highlight a specific provider on the Integrations page.
*
* @since 1.8.5.4
*/
private function modify_url() {
if ( $this->view !== 'integrations' ) {
return;
}
$_SERVER['REQUEST_URI'] = remove_query_arg( 'wpforms-integration' );
}
/**
* Display admin notice about using a downgraded version of WPForms.
*
* @since 1.8.5.4
*/
private function maybe_display_downgraded_notice() {
if ( ! $this->is_downgraded_version() ) {
return;
}
$notice = sprintf(
wp_kses( /* translators: %1$s - WPForms.com doc page URL; %2$s - button text. */
__(
'It looks like you\'ve downgraded to an older version of WPForms. We recommend always using the latest version as some features may not function as expected in older versions. <a href="%1$s" target="_blank" rel="noopener">%2$s</a>',
'wpforms-lite'
),
[
'a' => [
'href' => [],
'target' => [],
'rel' => [],
],
]
),
esc_url( wpforms_utm_link( 'https://wpforms.com/docs/why-you-should-always-use-the-latest-version-of-wpforms/', 'Settings', 'Downgrade notice' ) ),
esc_html__( 'Learn More', 'wpforms-lite' )
);
Notice::warning(
$notice,
[
'dismiss' => Notice::DISMISS_GLOBAL,
'slug' => 'wpforms_is_downgraded',
]
);
}
/**
* Check if plugin was downgraded.
*
* @since 1.8.5.4
*
* @return bool
*/
private function is_downgraded_version(): bool {
// Get all installed versions.
$installed_versions = wpforms()->is_pro() ? (array) get_option( Migrations::MIGRATED_OPTION_NAME, [] ) : (array) get_option( LiteMigration::MIGRATED_OPTION_NAME, [] );
// Get the most recent installed version.
$db_latest = array_keys( $installed_versions )[ count( $installed_versions ) - 1 ];
// Check if downgrade happened.
return version_compare( $db_latest, WPFORMS_VERSION, '>' );
}
/**
* Sanitize and save settings.
*
* @since 1.3.9
*/
public function save_settings() { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.MaxExceeded, Generic.Metrics.NestingLevel.MaxExceeded
// Check nonce and other various security checks.
if ( ! isset( $_POST['wpforms-settings-submit'] ) || empty( $_POST['nonce'] ) ) {
return;
}
if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'wpforms-settings-nonce' ) ) {
return;
}
if ( ! wpforms_current_user_can() ) {
return;
}
if ( empty( $_POST['view'] ) ) {
return;
}
$current_view = sanitize_key( $_POST['view'] );
// Get registered fields and current settings.
$fields = $this->get_registered_settings( $current_view );
$settings = get_option( 'wpforms_settings', [] );
// Views excluded from saving list.
$exclude_views = apply_filters( 'wpforms_settings_exclude_view', [], $fields, $settings );
if ( is_array( $exclude_views ) && in_array( $current_view, $exclude_views, true ) ) {
// Run a custom save processing for excluded views.
do_action( 'wpforms_settings_custom_process', $current_view, $fields, $settings );
return;
}
if ( empty( $fields ) || ! is_array( $fields ) ) {
return;
}
// Sanitize and prep each field.
foreach ( $fields as $id => $field ) {
// Certain field types are not valid for saving and are skipped.
$exclude = apply_filters( 'wpforms_settings_exclude_type', [ 'content', 'license', 'providers' ] );
if ( empty( $field['type'] ) || in_array( $field['type'], $exclude, true ) ) {
continue;
}
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
$value = isset( $_POST[ $id ] ) ? wp_unslash( $_POST[ $id ] ) : false;
$value_prev = isset( $settings[ $id ] ) ? $settings[ $id ] : false;
// Trim all string values.
if ( is_string( $value ) ) {
$value = trim( $value );
}
// Custom filter can be provided for sanitizing, otherwise use defaults.
if ( ! empty( $field['filter'] ) && is_callable( $field['filter'] ) ) {
$value = call_user_func( $field['filter'], $value, $id, $field, $value_prev );
} else {
switch ( $field['type'] ) {
case 'checkbox':
case 'toggle':
$value = (bool) $value;
break;
case 'image':
$value = esc_url_raw( $value );
break;
case 'color':
$value = wpforms_sanitize_hex_color( $value );
break;
case 'color_scheme':
$value = array_map( 'wpforms_sanitize_hex_color', $value );
break;
case 'number':
$value = (float) $value;
break;
case 'radio':
case 'select':
$value = $this->validate_field_with_options( $field, $value, $value_prev );
break;
case 'text':
default:
$value = sanitize_text_field( $value );
break;
}
}
// Add to settings.
$settings[ $id ] = $value;
}
// Save settings.
wpforms_update_settings( $settings );
Notice::success( esc_html__( 'Settings were successfully saved.', 'wpforms-lite' ) );
}
/**
* Enqueue assets for the settings page.
*
* @since 1.0.0
*/
public function enqueues() {
do_action( 'wpforms_settings_enqueue' );
}
/**
* Return registered settings tabs.
*
* @since 1.3.9
*
* @return array
*/
public function get_tabs() {
$tabs = [
'general' => [
'name' => esc_html__( 'General', 'wpforms-lite' ),
'form' => true,
'submit' => esc_html__( 'Save Settings', 'wpforms-lite' ),
],
'validation' => [
'name' => esc_html__( 'Validation', 'wpforms-lite' ),
'form' => true,
'submit' => esc_html__( 'Save Settings', 'wpforms-lite' ),
],
'integrations' => [
'name' => esc_html__( 'Integrations', 'wpforms-lite' ),
'form' => false,
'submit' => false,
],
'geolocation' => [
'name' => esc_html__( 'Geolocation', 'wpforms-lite' ),
'form' => false,
'submit' => false,
],
'misc' => [
'name' => esc_html__( 'Misc', 'wpforms-lite' ),
'form' => true,
'submit' => esc_html__( 'Save Settings', 'wpforms-lite' ),
],
];
return apply_filters( 'wpforms_settings_tabs', $tabs );
}
/**
* Output tab navigation area.
*
* @since 1.3.9
*/
public function tabs() {
$tabs = $this->get_tabs();
echo '<ul class="wpforms-admin-tabs">';
foreach ( $tabs as $id => $tab ) {
$active = $id === $this->view ? 'active' : '';
$link = add_query_arg( 'view', $id, admin_url( 'admin.php?page=wpforms-settings' ) );
echo '<li><a href="' . esc_url_raw( $link ) . '" class="' . esc_attr( $active ) . '">' . esc_html( $tab['name'] ) . '</a></li>';
}
echo '</ul>';
}
/**
* Return all the default registered settings fields.
*
* @since 1.3.9
*
* @param string $view The current view (tab) on Settings page.
*
* @return array
*/
public function get_registered_settings( $view = '' ) {
$defaults = [
// General Settings tab.
'general' => [
'license-heading' => [
'id' => 'license-heading',
'content' => '<h4>' . esc_html__( 'License', 'wpforms-lite' ) . '</h4><p>' . esc_html__( 'Your license key provides access to updates and addons.', 'wpforms-lite' ) . '</p>',
'type' => 'content',
'no_label' => true,
'class' => [ 'section-heading' ],
],
'license-key' => [
'id' => 'license-key',
'name' => esc_html__( 'License Key', 'wpforms-lite' ),
'type' => 'license',
],
'general-heading' => [
'id' => 'general-heading',
'content' => '<h4>' . esc_html__( 'General', 'wpforms-lite' ) . '</h4>',
'type' => 'content',
'no_label' => true,
'class' => [ 'section-heading', 'no-desc' ],
],
'disable-css' => [
'id' => 'disable-css',
'name' => esc_html__( 'Include Form Styling', 'wpforms-lite' ),
'desc' => sprintf(
wp_kses( /* translators: %s - WPForms.com form styling setting URL. */
__( 'Determines which CSS files to load and use for the site. "Base and Form Theme Styling" is recommended, unless you are experienced with CSS or instructed by support to change settings. <a href="%s" target="_blank" rel="noopener noreferrer" class="wpforms-learn-more">Learn More</a>', 'wpforms-lite' ),
[
'a' => [
'href' => [],
'target' => [],
'rel' => [],
'class' => [],
],
]
),
esc_url( wpforms_utm_link( 'https://wpforms.com/docs/how-to-choose-an-include-form-styling-setting/', 'settings-license', 'Form Styling Documentation' ) )
),
'type' => 'select',
'choicesjs' => true,
'default' => 1,
'options' => [
1 => esc_html__( 'Base and form theme styling', 'wpforms-lite' ),
2 => esc_html__( 'Base styling only', 'wpforms-lite' ),
3 => esc_html__( 'No styling', 'wpforms-lite' ),
],
],
'global-assets' => [
'id' => 'global-assets',
'name' => esc_html__( 'Load Assets Globally', 'wpforms-lite' ),
'desc' => esc_html__( 'Load WPForms assets site-wide. Only check if your site is having compatibility issues or instructed to by support.', 'wpforms-lite' ),
'type' => 'toggle',
'status' => true,
],
'gdpr-heading' => [
'id' => 'GDPR',
'content' => '<h4>' . esc_html__( 'GDPR', 'wpforms-lite' ) . '</h4>',
'type' => 'content',
'no_label' => true,
'class' => [ 'section-heading', 'no-desc' ],
],
'gdpr' => [
'id' => 'gdpr',
'name' => esc_html__( 'GDPR Enhancements', 'wpforms-lite' ),
'desc' => sprintf(
wp_kses( /* translators: %s - WPForms.com GDPR documentation URL. */
__( 'Enable GDPR related features and enhancements. <a href="%s" target="_blank" rel="noopener noreferrer" class="wpforms-learn-more">Learn More</a>', 'wpforms-lite' ),
[
'a' => [
'href' => [],
'target' => [],
'rel' => [],
'class' => [],
],
]
),
esc_url( wpforms_utm_link( 'https://wpforms.com/docs/how-to-create-gdpr-compliant-forms/', 'settings-license', 'GDPR Documentation' ) )
),
'type' => 'toggle',
'status' => true,
],
],
// Validation messages settings tab.
'validation' => [
'validation-heading' => [
'id' => 'validation-heading',
'content' => sprintf( /* translators: %s - WPForms.com smart tags documentation URL. */
esc_html__( '%1$s These messages are displayed to the users as they fill out a form in real-time. Messages can include plain text and/or %2$sSmart Tags%3$s.', 'wpforms-lite' ),
'<h4>' . esc_html__( 'Validation Messages', 'wpforms-lite' )
. '</h4><p>',
'<a href="' . esc_url( wpforms_utm_link( 'https://wpforms.com/docs/how-to-use-smart-tags-in-wpforms/#smart-tags', 'Settings - Validation', 'Smart Tag Documentation' ) ) . '" target="_blank" rel="noopener noreferrer">',
'</a>'
),
'type' => 'content',
'no_label' => true,
'class' => [ 'section-heading' ],
],
'validation-required' => [
'id' => 'validation-required',
'name' => esc_html__( 'Required', 'wpforms-lite' ),
'type' => 'text',
'default' => esc_html__( 'This field is required.', 'wpforms-lite' ),
],
'validation-email' => [
'id' => 'validation-email',
'name' => esc_html__( 'Email', 'wpforms-lite' ),
'type' => 'text',
'default' => esc_html__( 'Please enter a valid email address.', 'wpforms-lite' ),
],
'validation-email-suggestion' => [
'id' => 'validation-email-suggestion',
'name' => esc_html__( 'Email Suggestion', 'wpforms-lite' ),
'type' => 'text',
'default' => sprintf( /* translators: %s - suggested email address. */
esc_html__( 'Did you mean %s?', 'wpforms-lite' ),
'{suggestion}'
),
],
'validation-email-restricted' => [
'id' => 'validation-email-restricted',
'name' => esc_html__( 'Email Restricted', 'wpforms-lite' ),
'type' => 'text',
'default' => esc_html__( 'This email address is not allowed.', 'wpforms-lite' ),
],
'validation-number' => [
'id' => 'validation-number',
'name' => esc_html__( 'Number', 'wpforms-lite' ),
'type' => 'text',
'default' => esc_html__( 'Please enter a valid number.', 'wpforms-lite' ),
],
'validation-number-positive' => [
'id' => 'validation-number-positive',
'name' => esc_html__( 'Number Positive', 'wpforms-lite' ),
'type' => 'text',
'default' => esc_html__( 'Please enter a valid positive number.', 'wpforms-lite' ),
],
'validation-minimum-price' => [
'id' => 'validation-minimum-price',
'name' => esc_html__( 'Minimum Price', 'wpforms-lite' ),
'type' => 'text',
'default' => esc_html__( 'Amount entered is less than the required minimum.', 'wpforms-lite' ),
],
'validation-confirm' => [
'id' => 'validation-confirm',
'name' => esc_html__( 'Confirm Value', 'wpforms-lite' ),
'type' => 'text',
'default' => esc_html__( 'Field values do not match.', 'wpforms-lite' ),
],
'validation-inputmask-incomplete' => [
'id' => 'validation-inputmask-incomplete',
'name' => esc_html__( 'Input Mask Incomplete', 'wpforms-lite' ),
'type' => 'text',
'default' => esc_html__( 'Please fill out the field in required format.', 'wpforms-lite' ),
],
'validation-check-limit' => [
'id' => 'validation-check-limit',
'name' => esc_html__( 'Checkbox Selection Limit', 'wpforms-lite' ),
'type' => 'text',
'default' => esc_html__( 'You have exceeded the number of allowed selections: {#}.', 'wpforms-lite' ),
],
'validation-character-limit' => [
'id' => 'validation-character-limit',
'name' => esc_html__( 'Character Limit', 'wpforms-lite' ),
'type' => 'text',
'default' => sprintf( /* translators: %1$s - characters limit, %2$s - number of characters left. */
esc_html__( 'Limit is %1$s characters. Characters remaining: %2$s.', 'wpforms-lite' ),
'{limit}',
'{remaining}'
),
],
'validation-word-limit' => [
'id' => 'validation-word-limit',
'name' => esc_html__( 'Word Limit', 'wpforms-lite' ),
'type' => 'text',
'default' => sprintf( /* translators: %1$s - words limit, %2$s - number of words left. */
esc_html__( 'Limit is %1$s words. Words remaining: %2$s.', 'wpforms-lite' ),
'{limit}',
'{remaining}'
),
],
],
// Provider integrations settings tab.
'integrations' => [
'integrations-heading' => [
'id' => 'integrations-heading',
'content' => '<h4>' . esc_html__( 'Integrations', 'wpforms-lite' ) . '</h4><p>' . esc_html__( 'Manage integrations with popular providers such as Constant Contact, Mailchimp, Zapier, and more.', 'wpforms-lite' ) . '</p>',
'type' => 'content',
'no_label' => true,
'class' => [ 'section-heading' ],
],
'integrations-providers' => [
'id' => 'integrations-providers',
'content' => '<h4>' . esc_html__( 'Integrations', 'wpforms-lite' ) . '</h4><p>' . esc_html__( 'Manage integrations with popular providers such as Constant Contact, Mailchimp, Zapier, and more.', 'wpforms-lite' ) . '</p>',
'type' => 'providers',
'wrap' => 'none',
],
],
// Misc. settings tab.
'misc' => [
'misc-heading' => [
'id' => 'misc-heading',
'content' => '<h4>' . esc_html__( 'Miscellaneous', 'wpforms-lite' ) . '</h4>',
'type' => 'content',
'no_label' => true,
'class' => [ 'section-heading', 'no-desc' ],
],
'hide-announcements' => [
'id' => 'hide-announcements',
'name' => esc_html__( 'Hide Announcements', 'wpforms-lite' ),
'desc' => esc_html__( 'Hide plugin announcements and update details.', 'wpforms-lite' ),
'type' => 'toggle',
'status' => true,
],
'hide-admin-bar' => [
'id' => 'hide-admin-bar',
'name' => esc_html__( 'Hide Admin Bar Menu', 'wpforms-lite' ),
'desc' => esc_html__( 'Hide the WPForms admin bar menu.', 'wpforms-lite' ),
'type' => 'toggle',
'status' => true,
],
'uninstall-data' => [
'id' => 'uninstall-data',
'name' => esc_html__( 'Uninstall WPForms', 'wpforms-lite' ),
'desc' => $this->get_uninstall_desc(),
'type' => 'toggle',
'status' => true,
],
],
];
$defaults = apply_filters( 'wpforms_settings_defaults', $defaults );
// Take care of invalid views.
if ( ! empty( $view ) && ! array_key_exists( $view, $defaults ) ) {
$this->view = key( $defaults );
return reset( $defaults );
}
return empty( $view ) ? $defaults : $defaults[ $view ];
}
/**
* Get uninstall description.
*
* @since 1.8.4
*
* @return string
*/
private function get_uninstall_desc() {
$desc = esc_html__( 'Remove ALL WPForms data upon plugin deletion.', 'wpforms-lite' );
$warning = esc_html__( 'All forms and settings will be unrecoverable.', 'wpforms-lite' );
if ( wpforms()->is_pro() ) {
$desc = esc_html__( 'Remove ALL WPForms data upon plugin deletion.', 'wpforms-lite' );
$warning = esc_html__( 'All forms, entries, and uploaded files will be unrecoverable.', 'wpforms-lite' );
}
return sprintf( '%s <span class="wpforms-settings-warning">%s</span>', $desc, $warning );
}
/**
* Return array containing markup for all the appropriate settings fields.
*
* @since 1.3.9
*
* @param string $view View slug.
*
* @return array
*/
public function get_settings_fields( $view = '' ) {
$fields = [];
$settings = $this->get_registered_settings( $view );
foreach ( $settings as $id => $args ) {
$fields[ $id ] = wpforms_settings_output_field( $args );
}
return apply_filters( 'wpforms_settings_fields', $fields, $view );
}
/**
* Build the output for the plugin settings page.
*
* @since 1.0.0
*/
public function output() {
$tabs = $this->get_tabs();
$fields = $this->get_settings_fields( $this->view );
?>
<div id="wpforms-settings" class="wrap wpforms-admin-wrap">
<?php $this->tabs(); ?>
<h1 class="wpforms-h1-placeholder"></h1>
<?php
if ( wpforms()->is_pro() && class_exists( 'WPForms_License', false ) ) {
wpforms()->get( 'license' )->notices( true );
}
?>
<div class="wpforms-admin-content wpforms-admin-settings wpforms-admin-content-<?php echo esc_attr( $this->view ); ?> wpforms-admin-settings-<?php echo esc_attr( $this->view ); ?>">
<?php
// Some tabs rely on AJAX and do not contain a form, such as Integrations.
if ( ! empty( $tabs[ $this->view ]['form'] ) ) :
?>
<form class="wpforms-admin-settings-form" method="post">
<input type="hidden" name="action" value="update-settings">
<input type="hidden" name="view" value="<?php echo esc_attr( $this->view ); ?>">
<input type="hidden" name="nonce" value="<?php echo esc_attr( wp_create_nonce( 'wpforms-settings-nonce' ) ); ?>">
<?php endif; ?>
<?php do_action( 'wpforms_admin_settings_before', $this->view, $fields ); ?>
<?php
foreach ( $fields as $field ) {
echo $field; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
?>
<?php if ( ! empty( $tabs[ $this->view ]['submit'] ) ) : ?>
<p class="submit">
<button type="submit" class="wpforms-btn wpforms-btn-md wpforms-btn-orange" name="wpforms-settings-submit">
<?php
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo $tabs[ $this->view ]['submit'];
?>
</button>
</p>
<?php endif; ?>
<?php do_action( 'wpforms_admin_settings_after', $this->view, $fields ); ?>
<?php if ( ! empty( $tabs[ $this->view ]['form'] ) ) : ?>
</form>
<?php endif; ?>
</div>
</div>
<?php
}
/**
* Monitor that all custom tables exist and recreate if missing.
* This logic works on Settings > General page only.
*
* @since 1.6.2
*/
public function monitor_custom_tables() {
// Proceed on Settings plugin admin area page only.
if ( $this->view !== 'general' ) {
return;
}
/*
* Tasks Meta table.
*/
$meta = new \WPForms\Tasks\Meta();
if ( $meta->table_exists() ) {
return;
}
$meta->create_table();
}
/**
* Validate radio and select fields.
*
* @since 1.7.5.5
*
* @param array $field Field.
* @param mixed $value Value.
* @param mixed $value_prev Previous value.
*
* @return mixed
*/
private function validate_field_with_options( $field, $value, $value_prev ) {
$value = sanitize_text_field( $value );
if ( isset( $field['options'] ) && array_key_exists( $value, $field['options'] ) ) {
return $value;
}
return isset( $field['default'] ) ? $field['default'] : $value_prev;
}
}
new WPForms_Settings();

View File

@@ -0,0 +1,354 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Welcome page class.
*
* This page is shown when the plugin is activated.
*
* @since 1.0.0
*/
class WPForms_Welcome {
/**
* Hidden welcome page slug.
*
* @since 1.5.6
*/
const SLUG = 'wpforms-getting-started';
/**
* Primary class constructor.
*
* @since 1.0.0
*/
public function __construct() {
add_action( 'plugins_loaded', [ $this, 'hooks' ] );
}
/**
* Register all WP hooks.
*
* @since 1.5.6
*/
public function hooks() {
// If user is in admin ajax or doing cron, return.
if ( wp_doing_ajax() || wp_doing_cron() ) {
return;
}
// If user cannot manage_options, return.
if ( ! wpforms_current_user_can() ) {
return;
}
add_action( 'admin_menu', [ $this, 'register' ] );
add_action( 'admin_head', [ $this, 'hide_menu' ] );
add_action( 'admin_init', [ $this, 'redirect' ], 9999 );
}
/**
* Register the pages to be used for the Welcome screen (and tabs).
*
* These pages will be removed from the Dashboard menu, so they will
* not actually show. Sneaky, sneaky.
*
* @since 1.0.0
*/
public function register() {
// Getting started - shows after installation.
add_dashboard_page(
esc_html__( 'Welcome to WPForms', 'wpforms-lite' ),
esc_html__( 'Welcome to WPForms', 'wpforms-lite' ),
apply_filters( 'wpforms_welcome_cap', wpforms_get_capability_manage_options() ),
self::SLUG,
[ $this, 'output' ]
);
}
/**
* Removed the dashboard pages from the admin menu.
*
* This means the pages are still available to us, but hidden.
*
* @since 1.0.0
*/
public function hide_menu() {
remove_submenu_page( 'index.php', self::SLUG );
}
/**
* Welcome screen redirect.
*
* This function checks if a new install or update has just occurred. If so,
* then we redirect the user to the appropriate page.
*
* @since 1.0.0
*/
public function redirect() {
// Check if we should consider redirection.
if ( ! get_transient( 'wpforms_activation_redirect' ) ) {
return;
}
// If we are redirecting, clear the transient so it only happens once.
delete_transient( 'wpforms_activation_redirect' );
// Check option to disable welcome redirect.
if ( get_option( 'wpforms_activation_redirect', false ) ) {
return;
}
// Only do this for single site installs.
if ( isset( $_GET['activate-multi'] ) || is_network_admin() ) { // WPCS: CSRF ok.
return;
}
// Check if this is an update or first install.
$upgrade = get_option( 'wpforms_version_upgraded_from' );
if ( ! $upgrade ) {
// Initial install.
wp_safe_redirect( admin_url( 'index.php?page=' . self::SLUG ) );
exit;
}
}
/**
* Getting Started screen. Shows after first install.
*
* @since 1.0.0
*/
public function output() {
$class = wpforms()->is_pro() ? 'pro' : 'lite';
?>
<div id="wpforms-welcome" class="<?php echo sanitize_html_class( $class ); ?>">
<div class="container">
<div class="intro">
<div class="sullie">
<img src="<?php echo WPFORMS_PLUGIN_URL; ?>assets/images/sullie.png" alt="<?php esc_attr_e( 'Sullie the WPForms mascot', 'wpforms-lite' ); ?>">
</div>
<div class="block">
<h1><?php esc_html_e( 'Welcome to WPForms', 'wpforms-lite' ); ?></h1>
<h6><?php esc_html_e( 'Thank you for choosing WPForms - the most powerful drag & drop WordPress form builder in the market.', 'wpforms-lite' ); ?></h6>
</div>
<a href="#" class="play-video" title="<?php esc_attr_e( 'Watch how to create your first form', 'wpforms-lite' ); ?>">
<img src="<?php echo WPFORMS_PLUGIN_URL; ?>assets/images/welcome-video.png" alt="<?php esc_attr_e( 'Watch how to create your first form', 'wpforms-lite' ); ?>" class="video-thumbnail">
</a>
<div class="block">
<h6><?php esc_html_e( 'WPForms makes it easy to create forms in WordPress. You can watch the video tutorial or read our guide on how create your first form.', 'wpforms-lite' ); ?></h6>
<div class="button-wrap wpforms-clear">
<div class="left">
<a href="<?php echo esc_url( admin_url( 'admin.php?page=wpforms-builder' ) ); ?>" class="wpforms-btn wpforms-btn-block wpforms-btn-lg wpforms-btn-orange">
<?php esc_html_e( 'Create Your First Form', 'wpforms-lite' ); ?>
</a>
</div>
<div class="right">
<a href="<?php echo esc_url( wpforms_utm_link( 'https://wpforms.com/docs/creating-first-form/', 'welcome-page', 'Read the Full Guide' ) ); ?>"
class="wpforms-btn wpforms-btn-block wpforms-btn-lg wpforms-btn-grey" target="_blank" rel="noopener noreferrer">
<?php esc_html_e( 'Read the Full Guide', 'wpforms-lite' ); ?>
</a>
</div>
</div>
</div>
</div><!-- /.intro -->
<?php do_action( 'wpforms_welcome_intro_after' ); ?>
<div class="features">
<div class="block">
<h1><?php esc_html_e( 'WPForms Features &amp; Addons', 'wpforms-lite' ); ?></h1>
<h6><?php esc_html_e( 'WPForms is both easy to use and extremely powerful. We have tons of helpful features that allow us to give you everything you need from a form builder.', 'wpforms-lite' ); ?></h6>
<div class="feature-list wpforms-clear">
<div class="feature-block first">
<img src="<?php echo WPFORMS_PLUGIN_URL; ?>assets/images/welcome-feature-icon-1.png">
<h5><?php esc_html_e( 'Drag &amp; Drop Form Builder', 'wpforms-lite' ); ?></h5>
<p><?php esc_html_e( 'Easily create an amazing form in just a few minutes without writing any code.', 'wpforms-lite' ); ?></p>
</div>
<div class="feature-block last">
<img src="<?php echo WPFORMS_PLUGIN_URL; ?>assets/images/welcome-feature-icon-2.png">
<h5><?php esc_html_e( 'Form Templates', 'wpforms-lite' ); ?></h5>
<p><?php esc_html_e( 'Start with pre-built form templates to save even more time.', 'wpforms-lite' ); ?></p>
</div>
<div class="feature-block first">
<img src="<?php echo WPFORMS_PLUGIN_URL; ?>assets/images/welcome-feature-icon-3.png">
<h5><?php esc_html_e( 'Responsive Mobile Friendly', 'wpforms-lite' ); ?></h5>
<p><?php esc_html_e( 'WPForms is 100% responsive meaning it works on mobile, tablets & desktop.', 'wpforms-lite' ); ?></p>
</div>
<div class="feature-block last">
<img src="<?php echo WPFORMS_PLUGIN_URL; ?>assets/images/welcome-feature-icon-4.png">
<h5><?php esc_html_e( 'Smart Conditional Logic', 'wpforms-lite' ); ?></h5>
<p><?php esc_html_e( 'Easily create high performance forms with our smart conditional logic.', 'wpforms-lite' ); ?></p>
</div>
<div class="feature-block first">
<img src="<?php echo WPFORMS_PLUGIN_URL; ?>assets/images/welcome-feature-icon-5.png">
<h5><?php esc_html_e( 'Instant Notifications', 'wpforms-lite' ); ?></h5>
<p><?php esc_html_e( 'Respond to leads quickly with our instant form notification feature for your team.', 'wpforms-lite' ); ?></p>
</div>
<div class="feature-block last">
<img src="<?php echo WPFORMS_PLUGIN_URL; ?>assets/images/welcome-feature-icon-6.png">
<h5><?php esc_html_e( 'Entry Management', 'wpforms-lite' ); ?></h5>
<p><?php esc_html_e( 'View all your leads in one place to streamline your workflow.', 'wpforms-lite' ); ?></p>
</div>
<div class="feature-block first">
<img src="<?php echo WPFORMS_PLUGIN_URL; ?>assets/images/welcome-feature-icon-7.png">
<h5><?php esc_html_e( 'Payments Made Easy', 'wpforms-lite' ); ?></h5>
<p><?php esc_html_e( 'Easily collect payments, donations, and online orders without hiring a developer.', 'wpforms-lite' ); ?></p>
</div>
<div class="feature-block last">
<img src="<?php echo WPFORMS_PLUGIN_URL; ?>assets/images/welcome-feature-icon-8.png">
<h5><?php esc_html_e( 'Marketing &amp; Subscriptions', 'wpforms-lite' ); ?></h5>
<p><?php esc_html_e( 'Create subscription forms and connect with your email marketing service.', 'wpforms-lite' ); ?></p>
</div>
<div class="feature-block first">
<img src="<?php echo WPFORMS_PLUGIN_URL; ?>assets/images/welcome-feature-icon-9.png">
<h5><?php esc_html_e( 'Easy to Embed', 'wpforms-lite' ); ?></h5>
<p><?php esc_html_e( 'Easily embed your forms in blog posts, pages, sidebar widgets, footer, etc.', 'wpforms-lite' ); ?></p>
</div>
<div class="feature-block last">
<img src="<?php echo WPFORMS_PLUGIN_URL; ?>assets/images/welcome-feature-icon-10.png">
<h5><?php esc_html_e( 'Spam Protection', 'wpforms-lite' ); ?></h5>
<p><?php esc_html_e( 'Our smart captcha and spam protection automatically prevents spam submissions.', 'wpforms-lite' ); ?></p>
</div>
</div>
<div class="button-wrap">
<a href="<?php echo esc_url( wpforms_utm_link( 'https://wpforms.com/features/', 'welcome-page', 'See All Features' ) ); ?>"
class="wpforms-btn wpforms-btn-lg wpforms-btn-grey" rel="noopener noreferrer" target="_blank">
<?php esc_html_e( 'See All Features', 'wpforms-lite' ); ?>
</a>
</div>
</div>
</div><!-- /.features -->
<div class="upgrade-cta upgrade">
<div class="block wpforms-clear">
<div class="left">
<h2><?php esc_html_e( 'Upgrade to PRO', 'wpforms-lite' ); ?></h2>
<ul>
<li><span class="dashicons dashicons-yes"></span> <?php esc_html_e( 'Advanced Fields', 'wpforms-lite' ); ?></li>
<li><span class="dashicons dashicons-yes"></span> <?php esc_html_e( 'Conditional Logic', 'wpforms-lite' ); ?></li>
<li><span class="dashicons dashicons-yes"></span> <?php esc_html_e( 'Payment Forms', 'wpforms-lite' ); ?></li>
<li><span class="dashicons dashicons-yes"></span> <?php esc_html_e( 'Surveys & Polls', 'wpforms-lite' ); ?></li>
<li><span class="dashicons dashicons-yes"></span> <?php esc_html_e( 'Signatures', 'wpforms-lite' ); ?></li>
<li><span class="dashicons dashicons-yes"></span> <?php esc_html_e( 'Form Abandonment', 'wpforms-lite' ); ?></li>
<li><span class="dashicons dashicons-yes"></span> <?php esc_html_e( 'Entry Management', 'wpforms-lite' ); ?></li>
<li><span class="dashicons dashicons-yes"></span> <?php esc_html_e( 'File Uploads', 'wpforms-lite' ); ?></li>
<li><span class="dashicons dashicons-yes"></span> <?php esc_html_e( 'Geolocation', 'wpforms-lite' ); ?></li>
<li><span class="dashicons dashicons-yes"></span> <?php esc_html_e( 'Conversational Forms', 'wpforms-lite' ); ?></li>
<li><span class="dashicons dashicons-yes"></span> <?php esc_html_e( 'User Registration', 'wpforms-lite' ); ?></li>
<li><span class="dashicons dashicons-yes"></span> <?php esc_html_e( 'Marketing Integrations', 'wpforms-lite' ); ?></li>
</ul>
</div>
<div class="right">
<h2><span>PRO</span></h2>
<div class="price">
<span class="amount">199</span><br>
<span class="term"><?php esc_html_e( 'per year', 'wpforms-lite' ); ?></span>
</div>
<a href="<?php echo esc_url( wpforms_admin_upgrade_link( 'welcome', 'Upgrade Now CTA Section' ) ); ?>" rel="noopener noreferrer" target="_blank"
class="wpforms-btn wpforms-btn-block wpforms-btn-lg wpforms-btn-orange wpforms-upgrade-modal">
<?php esc_html_e( 'Upgrade Now', 'wpforms-lite' ); ?>
</a>
</div>
</div>
</div>
<div class="testimonials upgrade">
<div class="block">
<h1><?php esc_html_e( 'Testimonials', 'wpforms-lite' ); ?></h1>
<div class="testimonial-block wpforms-clear">
<img src="<?php echo WPFORMS_PLUGIN_URL; ?>assets/images/welcome-testimonial-bill.jpg">
<p><?php esc_html_e( 'WPForms is by far the easiest form plugin to use. My clients love it its one of the few plugins they can use without any training. As a developer I appreciate how fast, modern, clean and extensible it is.', 'wpforms-lite' ); ?>
<p>
<p><strong>Bill Erickson</strong>, Erickson Web Consulting</p>
</div>
<div class="testimonial-block wpforms-clear">
<img src="<?php echo WPFORMS_PLUGIN_URL; ?>assets/images/welcome-testimonial-david.jpg">
<p><?php esc_html_e( 'As a business owner, time is my most valuable asset. WPForms allow me to create smart online forms with just a few clicks. With their pre-built form templates and the drag & drop builder, I can create a new form that works in less than 2 minutes without writing a single line of code. Well worth the investment.', 'wpforms-lite' ); ?>
<p>
<p><strong>David Henzel</strong>, MaxCDN</p>
</div>
</div>
</div><!-- /.testimonials -->
<div class="footer">
<div class="block wpforms-clear">
<div class="button-wrap wpforms-clear">
<div class="left">
<a href="<?php echo esc_url( admin_url( 'admin.php?page=wpforms-builder' ) ); ?>"
class="wpforms-btn wpforms-btn-block wpforms-btn-lg wpforms-btn-orange">
<?php esc_html_e( 'Create Your First Form', 'wpforms-lite' ); ?>
</a>
</div>
<div class="right">
<a href="<?php echo esc_url( wpforms_admin_upgrade_link( 'welcome', 'Upgrade to WPForms Pro' ) ); ?>" target="_blank" rel="noopener noreferrer"
class="wpforms-btn wpforms-btn-block wpforms-btn-lg wpforms-btn-trans-green wpforms-upgrade-modal">
<span class="underline">
<?php esc_html_e( 'Upgrade to WPForms Pro', 'wpforms-lite' ); ?> <span class="dashicons dashicons-arrow-right"></span>
</span>
</a>
</div>
</div>
</div>
</div><!-- /.footer -->
</div><!-- /.container -->
</div><!-- /#wpforms-welcome -->
<?php
}
}
new WPForms_Welcome();

View File

@@ -0,0 +1,600 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
use WPForms\Forms\Locator;
use WPForms\Integrations\LiteConnect\LiteConnect;
use WPForms\Integrations\LiteConnect\Integration as LiteConnectIntegration;
/**
* Generate the table on the plugin overview page.
*
* @since 1.0.0
*/
class WPForms_Overview_Table extends WP_List_Table {
/**
* Number of forms to show per page.
*
* @since 1.0.0
*
* @var int
*/
public $per_page;
/**
* Number of forms in different views.
*
* @since 1.7.2
*
* @var array
*/
private $count;
/**
* Current view.
*
* @since 1.7.3
*
* @var string
*/
private $view;
/**
* Primary class constructor.
*
* @since 1.0.0
*/
public function __construct() {
// Utilize the parent constructor to build the main class properties.
parent::__construct(
[
'singular' => 'form',
'plural' => 'forms',
'ajax' => false,
]
);
add_filter( 'default_hidden_columns', [ $this, 'default_hidden_columns' ], 10, 2 );
// Determine the current view.
$this->view = wpforms()->get( 'forms_views' )->get_current_view();
// Default number of forms to show per page.
$this->per_page = (int) apply_filters( 'wpforms_overview_per_page', 20 );
}
/**
* Get the instance of a class and store it in itself.
*
* @since 1.7.5
*/
public static function get_instance() {
static $instance;
if ( ! $instance ) {
$instance = new self();
}
return $instance;
}
/**
* Retrieve the table columns.
*
* @since 1.0.0
*
* @return array $columns Array of all the list table columns.
*/
public function get_columns() {
$columns = [
'cb' => '<input type="checkbox" />',
'name' => esc_html__( 'Name', 'wpforms-lite' ),
'tags' => esc_html__( 'Tags', 'wpforms-lite' ),
'author' => esc_html__( 'Author', 'wpforms-lite' ),
'shortcode' => esc_html__( 'Shortcode', 'wpforms-lite' ),
'created' => esc_html__( 'Date', 'wpforms-lite' ),
];
if ( LiteConnect::is_allowed() && LiteConnect::is_enabled() ) {
$columns['entries'] = esc_html__( 'Entries', 'wpforms-lite' );
}
return apply_filters( 'wpforms_overview_table_columns', $columns );
}
/**
* Render the checkbox column.
*
* @since 1.0.0
*
* @param WP_Post $form Form.
*
* @return string
*/
public function column_cb( $form ) {
return '<input type="checkbox" name="form_id[]" value="' . absint( $form->ID ) . '" />';
}
/**
* Render the columns.
*
* @since 1.0.0
*
* @param WP_Post $form CPT object as a form representation.
* @param string $column_name Column Name.
*
* @return string
*/
public function column_default( $form, $column_name ) {
switch ( $column_name ) {
case 'id':
$value = $form->ID;
break;
case 'shortcode':
$value = '[wpforms id="' . $form->ID . '"]';
break;
// This slug is not changed to 'date' for backward compatibility.
case 'created':
if ( gmdate( 'Ymd', strtotime( $form->post_date ) ) === gmdate( 'Ymd', strtotime( $form->post_modified ) ) ) {
$value = wp_kses(
sprintf( /* translators: %1$s - Post created date. */
__( 'Created<br/>%1$s', 'wpforms-lite' ),
esc_html( wpforms_datetime_format( $form->post_date ) )
),
[ 'br' => [] ]
);
} else {
$value = wp_kses(
sprintf( /* translators: %1$s - Post modified date. */
__( 'Last Modified<br/>%1$s', 'wpforms-lite' ),
esc_html( wpforms_datetime_format( $form->post_modified ) )
),
[ 'br' => [] ]
);
}
break;
case 'entries':
$value = sprintf(
'<span class="wpforms-lite-connect-entries-count"><a href="%s" data-title="%s">%s%d</a></span>',
esc_url( admin_url( 'admin.php?page=wpforms-entries' ) ),
esc_attr__( 'Entries are securely backed up in the cloud. Upgrade to restore.', 'wpforms-lite' ),
'<svg viewBox="0 0 16 12"><path d="M10.8 2c1.475 0 2.675 1.175 2.775 2.625C15 5.125 16 6.475 16 8a3.6 3.6 0 0 1-3.6 3.6H4a3.98 3.98 0 0 1-4-4 4.001 4.001 0 0 1 2.475-3.7A4.424 4.424 0 0 1 6.8.4c1.4 0 2.625.675 3.425 1.675C10.4 2.025 10.6 2 10.8 2ZM4 10.4h8.4a2.4 2.4 0 0 0 0-4.8.632.632 0 0 0-.113.013.678.678 0 0 1-.112.012c.125-.25.225-.525.225-.825 0-.875-.725-1.6-1.6-1.6a1.566 1.566 0 0 0-1.05.4 3.192 3.192 0 0 0-2.95-2 3.206 3.206 0 0 0-3.2 3.2v.05A2.757 2.757 0 0 0 1.2 7.6 2.795 2.795 0 0 0 4 10.4Zm6.752-4.624a.64.64 0 1 0-.905-.905L6.857 7.86 5.38 6.352a.64.64 0 1 0-.914.896l1.93 1.97a.64.64 0 0 0 .91.004l3.446-3.446Z"/></svg>',
LiteConnectIntegration::get_form_entries_count( $form->ID )
);
break;
case 'modified':
$value = get_post_modified_time( get_option( 'date_format' ), false, $form );
break;
case 'author':
$value = '';
$author = get_userdata( $form->post_author );
if ( ! $author ) {
break;
}
$value = $author->display_name;
$user_edit_url = get_edit_user_link( $author->ID );
if ( ! empty( $user_edit_url ) ) {
$value = '<a href="' . esc_url( $user_edit_url ) . '">' . esc_html( $value ) . '</a>';
}
break;
case 'php':
$value = '<code style="display:block;font-size:11px;">if( function_exists( \'wpforms_get\' ) ){ wpforms_get( ' . $form->ID . ' ); }</code>';
break;
default:
$value = '';
}
return apply_filters( 'wpforms_overview_table_column_value', $value, $form, $column_name );
}
/**
* Filter the default list of hidden columns.
*
* @since 1.7.2
*
* @param string[] $hidden Array of IDs of columns hidden by default.
* @param WP_Screen $screen WP_Screen object of the current screen.
*
* @return string[]
*/
public function default_hidden_columns( $hidden, $screen ) {
if ( $screen->id !== 'toplevel_page_wpforms-overview' ) {
return $hidden;
}
return [
'tags',
'author',
Locator::COLUMN_NAME,
];
}
/**
* Render the form name column with action links.
*
* @since 1.0.0
*
* @param WP_Post $form Form.
*
* @return string
*/
public function column_name( $form ) {
// Build the row action links and return the value.
return $this->get_column_name_title( $form ) . $this->get_column_name_row_actions( $form );
}
/**
* Render the form tags column.
*
* @since 1.7.5
*
* @param WP_Post $form Form.
*
* @return string
*/
public function column_tags( $form ) {
return wpforms()->get( 'forms_tags' )->column_tags( $form );
}
/**
* Get the form name HTML for the form name column.
*
* @since 1.5.8
*
* @param WP_Post $form Form object.
*
* @return string
*/
protected function get_column_name_title( $form ) {
$title = ! empty( $form->post_title ) ? $form->post_title : $form->post_name;
$name = sprintf(
'<span><strong>%s</strong></span>',
esc_html( $title )
);
if ( $this->view === 'trash' ) {
return $name;
}
if ( wpforms_current_user_can( 'view_form_single', $form->ID ) ) {
$name = sprintf(
'<a href="%s" title="%s" class="row-title" target="_blank" rel="noopener noreferrer"><strong>%s</strong></a>',
esc_url( wpforms_get_form_preview_url( $form->ID ) ),
esc_attr__( 'View preview', 'wpforms-lite' ),
esc_html( $title )
);
}
if ( wpforms_current_user_can( 'view_entries_form_single', $form->ID ) ) {
$name = sprintf(
'<a href="%s" title="%s"><strong>%s</strong></a>',
esc_url(
add_query_arg(
[
'view' => 'list',
'form_id' => $form->ID,
],
admin_url( 'admin.php?page=wpforms-entries' )
)
),
esc_attr__( 'View entries', 'wpforms-lite' ),
esc_html( $title )
);
}
if ( wpforms_current_user_can( 'edit_form_single', $form->ID ) ) {
$name = sprintf(
'<a href="%s" title="%s"><strong>%s</strong></a>',
esc_url(
add_query_arg(
[
'view' => 'fields',
'form_id' => $form->ID,
],
admin_url( 'admin.php?page=wpforms-builder' )
)
),
esc_attr__( 'Edit This Form', 'wpforms-lite' ),
esc_html( $title )
);
}
return $name;
}
/**
* Get the row actions HTML for the form name column.
*
* @since 1.5.8
*
* @param WP_Post $form Form object.
*
* @return string
*/
protected function get_column_name_row_actions( $form ) {
// phpcs:disable WPForms.Comments.PHPDocHooks.RequiredHookDocumentation, WPForms.PHP.ValidateHooks.InvalidHookName
/**
* Filters row action links on the 'All Forms' admin page.
*
* @since 1.0.0
*
* @param array $row_actions An array of action links for a given form.
* @param WP_Post $form Form object.
*/
return $this->row_actions( apply_filters( 'wpforms_overview_row_actions', [], $form ) );
// phpcs:enable
}
/**
* Define bulk actions available for our table listing.
*
* @since 1.0.0
*
* @return array
*/
public function get_bulk_actions() {
return wpforms()->get( 'forms_bulk_actions' )->get_dropdown_items();
}
/**
* Generate the table navigation above or below the table.
*
* @since 1.7.2
*
* @param string $which The location of the table navigation: 'top' or 'bottom'.
*/
protected function display_tablenav( $which ) {
// If there are some forms just call the parent method.
if ( $this->has_items() ) {
parent::display_tablenav( $which );
return;
}
// Otherwise, display bulk actions menu and "0 items" on the right (pagination).
?>
<div class="tablenav <?php echo esc_attr( $which ); ?>">
<div class="alignleft actions bulkactions">
<?php $this->bulk_actions( $which ); ?>
</div>
<?php
$this->extra_tablenav( $which );
if ( $which === 'top' ) {
$this->pagination( $which );
}
?>
<br class="clear" />
</div>
<?php
}
/**
* Extra controls to be displayed between bulk actions and pagination.
*
* @since 1.7.3
*
* @param string $which The location of the table navigation: 'top' or 'bottom'.
*/
protected function extra_tablenav( $which ) {
wpforms()->get( 'forms_tags' )->extra_tablenav( $which, $this );
wpforms()->get( 'forms_views' )->extra_tablenav( $which );
}
/**
* Message to be displayed when there are no forms.
*
* @since 1.0.0
*/
public function no_items() {
esc_html_e( 'No forms found.', 'wpforms-lite' );
}
/**
* Fetch and set up the final data for the table.
*
* @since 1.0.0
*/
public function prepare_items() {
// Set up the columns.
$columns = $this->get_columns();
// Hidden columns (none).
$hidden = get_hidden_columns( $this->screen );
// Define which columns can be sorted - form name, author, date.
$sortable = [
'name' => [ 'title', false ],
'author' => [ 'author', false ],
'created' => [ 'date', false ],
];
// Set column headers.
$this->_column_headers = [ $columns, $hidden, $sortable ];
// phpcs:disable WordPress.Security.NonceVerification.Recommended
$page = $this->get_pagenum();
$order = isset( $_GET['order'] ) && $_GET['order'] === 'asc' ? 'ASC' : 'DESC';
$orderby = isset( $_GET['orderby'] ) ? sanitize_key( $_GET['orderby'] ) : 'ID';
$per_page = $this->get_items_per_page( 'wpforms_forms_per_page', $this->per_page );
// phpcs:enable WordPress.Security.NonceVerification.Recommended
if ( $orderby === 'date' ) {
$orderby = [
'modified' => $order,
'date' => $order,
];
}
$args = [
'orderby' => $orderby,
'order' => $order,
'nopaging' => false,
'posts_per_page' => $per_page,
'paged' => $page,
'no_found_rows' => false,
'post_status' => 'publish',
];
/**
* Filters the `get_posts()` arguments while preparing items for the forms overview table.
*
* @since 1.7.3
*
* @param array $args Arguments array.
*/
$args = (array) apply_filters( 'wpforms_overview_table_prepare_items_args', $args );
// Giddy up.
$this->items = wpforms()->get( 'form' )->get( '', $args );
$per_page = isset( $args['posts_per_page'] ) ? $args['posts_per_page'] : $this->get_items_per_page( 'wpforms_forms_per_page', $this->per_page );
$this->update_count( $args );
$count_current_view = empty( $this->count[ $this->view ] ) ? 0 : $this->count[ $this->view ];
// Finalize pagination.
$this->set_pagination_args(
[
'total_items' => $count_current_view,
'per_page' => $per_page,
'total_pages' => ceil( $count_current_view / $per_page ),
]
);
}
/**
* Calculate and update form counts.
*
* @since 1.7.2
*
* @param array $args Get forms arguments.
*/
private function update_count( $args ) {
/**
* Allow counting forms filtered by a given search criteria.
*
* If result will not contain `all` key, count All Forms without filtering will be performed.
*
* @since 1.7.2
*
* @param array $count Contains counts of forms in different views.
* @param array $args Arguments of the `get_posts`.
*/
$this->count = (array) apply_filters( 'wpforms_overview_table_update_count', [], $args );
// We do not need to perform all forms count if we have the result already.
if ( isset( $this->count['all'] ) ) {
return;
}
// Count all forms.
$this->count['all'] = wpforms_current_user_can( 'wpforms_view_others_forms' )
? (int) wp_count_posts( 'wpforms' )->publish
: (int) count_user_posts( get_current_user_id(), 'wpforms', true );
/**
* Filters forms count data after counting all forms.
*
* This filter executes only if the result of `wpforms_overview_table_update_count` filter
* doesn't contain `all` key.
*
* @since 1.7.3
*
* @param array $count Contains counts of forms in different views.
* @param array $args Arguments of the `get_posts`.
*/
$this->count = (array) apply_filters( 'wpforms_overview_table_update_count_all', $this->count, $args );
}
/**
* Display the pagination.
*
* @since 1.7.2
*
* @param string $which The location of the table pagination: 'top' or 'bottom'.
*/
protected function pagination( $which ) {
if ( $this->has_items() ) {
parent::pagination( $which );
return;
}
printf(
'<div class="tablenav-pages one-page">
<span class="displaying-num">%s</span>
</div>',
esc_html__( '0 items', 'wpforms-lite' )
);
}
/**
* Extending the `display_rows()` method in order to add hooks.
*
* @since 1.5.6
*/
public function display_rows() {
do_action( 'wpforms_admin_overview_before_rows', $this );
parent::display_rows();
do_action( 'wpforms_admin_overview_after_rows', $this );
}
/**
* Forms search markup.
*
* @since 1.7.2
*
* @param string $text The 'submit' button label.
* @param string $input_id ID attribute value for the search input field.
*/
public function search_box( $text, $input_id ) {
wpforms()->get( 'forms_search' )->search_box( $text, $input_id );
}
/**
* Get the list of views available on forms overview table.
*
* @since 1.7.3
*/
protected function get_views() {
return wpforms()->get( 'forms_views' )->get_views();
}
}

View File

@@ -0,0 +1,283 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Primary overview page inside the admin which lists all forms.
*
* @since 1.0.0
*/
class WPForms_Overview {
/**
* Overview Table instance.
*
* @since 1.7.2
*
* @var WPForms_Overview_Table
*/
private $overview_table;
/**
* Primary class constructor.
*
* @since 1.0.0
*/
public function __construct() {
// Maybe load overview page.
add_action( 'admin_init', [ $this, 'init' ] );
// Setup screen options. Needs to be here as admin_init hook it too late.
add_action( 'load-toplevel_page_wpforms-overview', [ $this, 'screen_options' ] );
add_filter( 'set-screen-option', [ $this, 'screen_options_set' ], 10, 3 );
add_filter( 'set_screen_option_wpforms_forms_per_page', [ $this, 'screen_options_set' ], 10, 3 );
}
/**
* Determine if the user is viewing the overview page, if so, party on.
*
* @since 1.0.0
*/
public function init() {
// Only load if we are actually on the overview page.
if ( ! wpforms_is_admin_page( 'overview' ) ) {
return;
}
// Avoid recursively include _wp_http_referer in the REQUEST_URI.
$this->remove_referer();
add_action( 'current_screen', [ $this, 'init_overview_table' ] );
// The overview page leverages WP_List_Table so we must load it.
if ( ! class_exists( 'WP_List_Table', false ) ) {
require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
}
add_action( 'admin_enqueue_scripts', [ $this, 'enqueues' ] );
add_action( 'wpforms_admin_page', [ $this, 'output' ] );
// Provide hook for addons.
do_action( 'wpforms_overview_init' );
}
/**
* Init overview table class.
*
* @since 1.7.2
*/
public function init_overview_table() {
// Load the class that builds the overview table.
require_once WPFORMS_PLUGIN_DIR . 'includes/admin/overview/class-overview-table.php';
$this->overview_table = WPForms_Overview_Table::get_instance();
}
/**
* Remove previous `_wp_http_referer` variable from the REQUEST_URI.
*
* @since 1.7.2
*/
private function remove_referer() {
if ( isset( $_SERVER['REQUEST_URI'] ) ) {
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
$_SERVER['REQUEST_URI'] = remove_query_arg( '_wp_http_referer', wp_unslash( $_SERVER['REQUEST_URI'] ) );
}
}
/**
* Add per-page screen option to the Forms table.
*
* @since 1.0.0
*/
public function screen_options() {
$screen = get_current_screen();
if ( $screen === null || $screen->id !== 'toplevel_page_wpforms-overview' ) {
return;
}
add_screen_option(
'per_page',
[
'label' => esc_html__( 'Number of forms per page:', 'wpforms-lite' ),
'option' => 'wpforms_forms_per_page',
'default' => apply_filters( 'wpforms_overview_per_page', 20 ),
]
);
}
/**
* Form table per-page screen option value.
*
* @since 1.0.0
*
* @param bool $keep Whether to save or skip saving the screen option value. Default false.
* @param string $option The option name.
* @param int $value The number of rows to use.
*
* @return mixed
*/
public function screen_options_set( $keep, $option, $value ) {
if ( $option === 'wpforms_forms_per_page' ) {
return $value;
}
return $keep;
}
/**
* Enqueue assets for the overview page.
*
* @since 1.0.0
*/
public function enqueues() {
$min = wpforms_get_min_suffix();
wp_enqueue_script(
'wpforms-admin-forms-overview',
WPFORMS_PLUGIN_URL . "assets/js/components/admin/forms/overview{$min}.js",
[ 'jquery' ],
WPFORMS_VERSION,
true
);
// Hook for addons.
do_action( 'wpforms_overview_enqueue' );
}
/**
* Determine if it is an empty state.
*
* @since 1.7.5
*/
private function is_empty_state() {
// phpcs:disable WordPress.Security.NonceVerification.Recommended
return empty( $this->overview_table->items ) &&
! isset( $_GET['search']['term'] ) &&
! isset( $_GET['status'] ) &&
! isset( $_GET['tags'] ) &&
array_sum( wpforms()->get( 'forms_views' )->get_count() ) === 0;
// phpcs:enable WordPress.Security.NonceVerification.Recommended
}
/**
* Build the output for the overview page.
*
* @since 1.0.0
*/
public function output() {
?>
<div id="wpforms-overview" class="wrap wpforms-admin-wrap">
<h1 class="page-title">
<?php esc_html_e( 'Forms Overview', 'wpforms-lite' ); ?>
<?php if ( wpforms_current_user_can( 'create_forms' ) ) : ?>
<a href="<?php echo esc_url( admin_url( 'admin.php?page=wpforms-builder&view=setup' ) ); ?>" class="page-title-action wpforms-btn add-new-h2 wpforms-btn-orange" data-action="add">
<svg viewBox="0 0 14 14" class="page-title-action-icon">
<path d="M14 5.385v3.23H8.615V14h-3.23V8.615H0v-3.23h5.385V0h3.23v5.385H14Z"/>
</svg>
<span class="page-title-action-text"><?php esc_html_e( 'Add New', 'wpforms-lite' ); ?></span>
</a>
<?php endif; ?>
</h1>
<div class="wpforms-admin-content">
<?php
$this->overview_table->prepare_items();
// phpcs:disable WPForms.PHP.ValidateHooks.InvalidHookName
/**
* Fires before forms overview list table output.
*
* @since 1.6.0.1
*/
do_action( 'wpforms_admin_overview_before_table' );
// phpcs:enable WPForms.PHP.ValidateHooks.InvalidHookName
if ( $this->is_empty_state() ) {
// Output no forms screen.
echo wpforms_render( 'admin/empty-states/no-forms' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
} else {
?>
<form id="wpforms-overview-table" method="get" action="<?php echo esc_url( admin_url( 'admin.php?page=wpforms-overview' ) ); ?>">
<input type="hidden" name="post_type" value="wpforms" />
<input type="hidden" name="page" value="wpforms-overview" />
<?php
$this->overview_table->search_box( esc_html__( 'Search Forms', 'wpforms-lite' ), 'wpforms-overview-search' );
$this->overview_table->views();
$this->overview_table->display();
?>
</form>
<?php } ?>
</div>
</div>
<?php
}
/**
* Admin notices.
*
* @since 1.5.7
* @deprecated 1.7.3
*/
public function notices() {
_deprecated_function( __METHOD__, '1.7.3 of the WPForms', "wpforms()->get( 'forms_bulk_actions' )->notices()" );
wpforms()->get( 'forms_bulk_actions' )->notices();
}
/**
* Process the bulk table actions.
*
* @since 1.5.7
* @deprecated 1.7.3
*/
public function process_bulk_actions() {
_deprecated_function( __METHOD__, '1.7.3 of the WPForms', "wpforms()->get( 'forms_bulk_actions' )->process()" );
wpforms()->get( 'forms_bulk_actions' )->process();
}
/**
* Remove certain arguments from a query string that WordPress should always hide for users.
*
* @since 1.5.7
* @deprecated 1.7.3
*
* @param array $removable_query_args An array of parameters to remove from the URL.
*
* @return array Extended/filtered array of parameters to remove from the URL.
*/
public function removable_query_args( $removable_query_args ) {
_deprecated_function( __METHOD__, '1.7.3 of the WPForms', "wpforms()->get( 'forms_bulk_actions' )->removable_query_args()" );
return wpforms()->get( 'forms_bulk_actions' )->removable_query_args( $removable_query_args );
}
}
new WPForms_Overview();

View File

@@ -0,0 +1,706 @@
<?php
/**
* Settings API.
*
* @since 1.3.7
*/
use WPForms\Admin\Education\Helpers as EducationHelpers;
/**
* Settings output wrapper.
*
* @since 1.3.9
*
* @param array $args
*
* @return string
*/
function wpforms_settings_output_field( $args ) {
// Define default callback for this field type.
$callback = ! empty( $args['type'] ) && function_exists( 'wpforms_settings_' . $args['type'] . '_callback' ) ? 'wpforms_settings_' . $args['type'] . '_callback' : 'wpforms_settings_missing_callback';
// Allow custom callback to be provided via arg.
if ( ! empty( $args['callback'] ) && function_exists( $args['callback'] ) ) {
$callback = $args['callback'];
}
// Store returned markup from callback.
$field = call_user_func( $callback, $args );
// Allow arg to bypass standard field wrap for custom display.
if ( ! empty( $args['wrap'] ) ) {
return $field;
}
// Default class names.
$class = [
'wpforms-setting-row',
"wpforms-setting-row-{$args['type']}",
'wpforms-clear',
];
// Row attributes.
$wrapper_attributes = wpforms_html_attributes(
'wpforms-setting-row-' . wpforms_sanitize_key( $args['id'] ),
! empty( $args['class'] ) ? array_merge( $class, (array) $args['class'] ) : $class,
! empty( $args['data_attributes'] ) && is_array( $args['data_attributes'] ) ? $args['data_attributes'] : [],
! empty( $args['is_hidden'] ) ? [ 'style' => 'display:none;' ] : []
);
// Build standard field markup and return.
$output = "<div {$wrapper_attributes}>";
if ( ! empty( $args['name'] ) && empty( $args['no_label'] ) ) {
$output .= '<span class="wpforms-setting-label">';
$output .= '<label for="wpforms-setting-' . wpforms_sanitize_key( $args['id'] ) . '">' . esc_html( $args['name'] );
// Add education badge, if needed.
// The badge should be added after the label text, but before the label closing tag.
if ( ! empty( $args['education_badge'] ) ) {
$output .= wp_kses( $args['education_badge'], [ 'span' => [ 'class' => [] ] ] );
}
$output .= '</label>';
$output .= '</span>';
}
$output .= '<span class="wpforms-setting-field">';
$output .= $field;
if ( ! empty( $args['desc_after'] ) ) {
$output .= '<div class="wpforms-clear">' . $args['desc_after'] . '</div>';
}
$output .= '</span>';
$output .= '</div>';
return $output;
}
/**
* Missing Callback.
*
* If a function is missing for settings callbacks alert the user.
*
* @since 1.3.9
*
* @param array $args Arguments passed by the setting.
*
* @return string
*/
function wpforms_settings_missing_callback( $args ) {
return sprintf(
/* translators: %s - ID of a setting. */
esc_html__( 'The callback function used for the %s setting is missing.', 'wpforms-lite' ),
'<strong>' . wpforms_sanitize_key( $args['id'] ) . '</strong>'
);
}
/**
* Settings content field callback.
*
* @since 1.3.9
*
* @param array $args
*
* @return string
*/
function wpforms_settings_content_callback( $args ) {
return ! empty( $args['content'] ) ? $args['content'] : '';
}
/**
* Settings license field callback.
*
* @since 1.3.9
*
* @param array $args Settings arguments.
*
* @return string
*/
function wpforms_settings_license_callback( $args ) {
$output = '<p>' . esc_html__( 'You\'re using WPForms Lite - no license needed. Enjoy!', 'wpforms-lite' ) . ' 🙂</p>';
$output .=
'<p>' .
sprintf(
wp_kses( /* translators: %s - WPForms.com upgrade URL. */
__( 'To unlock more features consider <strong><a href="%s" target="_blank" rel="noopener noreferrer" class="wpforms-upgrade-modal">upgrading to PRO</a></strong>.', 'wpforms-lite' ),
[
'a' => [
'href' => [],
'class' => [],
'target' => [],
'rel' => [],
],
'strong' => [],
]
),
esc_url( wpforms_admin_upgrade_link( 'settings-license', 'Upgrade to WPForms Pro text Link' ) )
) .
'</p>';
$output .=
'<p class="discount-note">' .
wp_kses(
__( 'As a valued WPForms Lite user you receive <strong>50% off</strong>, automatically applied at checkout!', 'wpforms-lite' ),
[
'strong' => [],
]
) .
'</p>';
$output .= '<hr><p>' . esc_html__( 'Already purchased? Simply enter your license key below to enable WPForms PRO!', 'wpforms-lite' ) . '</p>';
$output .= '<p>';
$output .= '<input type="password" spellcheck="false" id="wpforms-settings-upgrade-license-key" placeholder="' . esc_attr__( 'Paste license key here', 'wpforms-lite' ) . '" value="">';
$output .= '<button class="wpforms-btn wpforms-btn-md wpforms-btn-blue" id="wpforms-settings-connect-btn">' . esc_html__( 'Verify Key', 'wpforms-lite' ) . '</button>';
$output .= '</p>';
/**
* Filter license settings HTML output.
*
* @since 1.7.9
*
* @param string $output HTML markup to be rendered in place of license settings.
*/
return apply_filters( 'wpforms_settings_license_output', $output );
}
/**
* Settings text input field callback.
*
* @since 1.3.9
*
* @param array $args Settings arguments.
*
* @return string
*/
function wpforms_settings_text_callback( $args ) {
if ( ! in_array( $args['type'], [ 'text', 'password' ], true ) ) {
$args['type'] = 'text';
}
$default = isset( $args['default'] ) ? esc_html( $args['default'] ) : '';
$value = wpforms_setting( $args['id'], $default );
$id = wpforms_sanitize_key( $args['id'] );
$output = '<input type="' . esc_attr( $args['type'] ) . '" id="wpforms-setting-' . $id . '" name="' . $id . '" value="' . esc_attr( $value ) . '">';
if ( ! empty( $args['desc'] ) ) {
$output .= '<p class="desc">' . wp_kses_post( $args['desc'] ) . '</p>';
}
return $output;
}
/**
* Settings password input field callback.
*
* @since 1.8.4
*
* @param array $args Setting field arguments.
*
* @return string
*/
function wpforms_settings_password_callback( $args ) {
return wpforms_settings_text_callback( $args );
}
/**
* Settings number input field callback.
*
* @since 1.5.3
*
* @param array $args Setting field arguments.
*
* @return string
*/
function wpforms_settings_number_callback( $args ) {
$default = isset( $args['default'] ) ? esc_html( $args['default'] ) : '';
$id = 'wpforms-setting-' . wpforms_sanitize_key( $args['id'] );
$attr = [
'value' => wpforms_setting( $args['id'], $default ),
'name' => wpforms_sanitize_key( $args['id'] ),
];
$data = ! empty( $args['data'] ) ? $args['data'] : [];
if ( ! empty( $args['attr'] ) ) {
$attr = array_merge( $attr, $args['attr'] );
}
$output = sprintf(
'<input type="number" %s>',
wpforms_html_attributes( $id, [], $data, $attr )
);
if ( ! empty( $args['desc'] ) ) {
$output .= '<p class="desc">' . wp_kses_post( $args['desc'] ) . '</p>';
}
return $output;
}
/**
* Settings select field callback.
*
* @since 1.3.9
*
* @param array $args
*
* @return string
*/
function wpforms_settings_select_callback( $args ) {
$default = isset( $args['default'] ) ? esc_html( $args['default'] ) : '';
$value = wpforms_setting( $args['id'], $default );
$id = wpforms_sanitize_key( $args['id'] );
$select_name = $id;
$class = ! empty( $args['choicesjs'] ) ? 'choicesjs-select' : '';
$choices = ! empty( $args['choicesjs'] ) ? true : false;
$data = isset( $args['data'] ) ? (array) $args['data'] : [];
$attr = isset( $args['attr'] ) ? (array) $args['attr'] : [];
if ( $choices && ! empty( $args['search'] ) ) {
$data['search'] = 'true';
}
if ( ! empty( $args['placeholder'] ) ) {
$data['placeholder'] = $args['placeholder'];
}
$size_attr = '';
if ( $choices && ! empty( $args['multiple'] ) ) {
$attr[] = 'multiple';
$select_name = $id . '[]';
$size_attr = ' size="1"';
}
foreach ( $data as $name => $val ) {
$data[ $name ] = 'data-' . sanitize_html_class( $name ) . '="' . esc_attr( $val ) . '"';
}
$data = implode( ' ', $data );
$attr = implode( ' ', array_map( 'sanitize_html_class', $attr ) );
$output = $choices ? '<span class="choicesjs-select-wrap">' : '';
$output .= '<select id="wpforms-setting-' . $id . '" name="' . $select_name . '" class="' . $class . '"' . $data . $attr . $size_attr . '>';
foreach ( $args['options'] as $option => $name ) {
if ( empty( $args['selected'] ) ) {
$selected = selected( $value, $option, false );
} else {
$selected = is_array( $args['selected'] ) && in_array( $option, $args['selected'], true ) ? 'selected' : '';
}
$output .= '<option value="' . esc_attr( $option ) . '" ' . $selected . '>' . esc_html( $name ) . '</option>';
}
$output .= '</select>';
$output .= $choices ? '</span>' : '';
if ( ! empty( $args['desc'] ) ) {
$output .= '<p class="desc">' . wp_kses_post( $args['desc'] ) . '</p>';
}
return $output;
}
/**
* Settings checkbox field callback.
*
* @since 1.3.9
*
* @param array $args
*
* @return string
*/
function wpforms_settings_checkbox_callback( $args ) {
$value = wpforms_setting( $args['id'] );
$id = wpforms_sanitize_key( $args['id'] );
$checked = ! empty( $value ) ? checked( 1, $value, false ) : '';
$disabled = ! empty( $args['disabled'] ) ? ' disabled' : '';
$output = '<input type="checkbox" id="wpforms-setting-' . $id . '" name="' . $id . '" ' . $checked . $disabled . '>';
if ( ! empty( $args['desc'] ) ) {
$output .= '<p class="desc">' . wp_kses_post( $args['desc'] ) . '</p>';
}
if ( ! empty( $args['disabled_desc'] ) ) {
$output .= '<p class="disabled-desc">' . wp_kses_post( $args['disabled_desc'] ) . '</p>';
}
return $output;
}
/**
* Settings radio field callback.
*
* @since 1.3.9
*
* @param array $args
*
* @return string
*/
function wpforms_settings_radio_callback( $args ) {
$default = isset( $args['default'] ) ? esc_html( $args['default'] ) : '';
$value = wpforms_setting( $args['id'], $default );
$id = wpforms_sanitize_key( $args['id'] );
$output = '';
$x = 1;
foreach ( $args['options'] as $option => $name ) {
$checked = checked( $value, $option, false );
$output .= '<span class="wpforms-settings-field-radio-wrapper">';
$output .= '<input type="radio" id="wpforms-setting-' . $id . '[' . $x . ']" name="' . $id . '" value="' . esc_attr( $option ) . '" ' . $checked . '>';
$output .= '<label for="wpforms-setting-' . $id . '[' . $x . ']" class="option-' . sanitize_html_class( $option ) . '">';
$output .= esc_html( $name );
$output .= '</label>';
$output .= '</span>';
$x ++;
}
if ( ! empty( $args['desc'] ) ) {
$output .= '<p class="desc">' . wp_kses_post( $args['desc'] ) . '</p>';
}
return $output;
}
/**
* Email template endpoint field callback.
*
* @since 1.8.5
*
* @param array $args Field arguments.
*
* @return string
*/
function wpforms_settings_email_template_callback( $args ) {
$id = wpforms_sanitize_key( $args['id'] );
$is_pro = wpforms()->is_pro();
$output = '';
$x = 1;
$education_args = [
'name' => esc_html__( 'Email Templates', 'wpforms-lite' ),
'plural' => '1',
'action' => 'upgrade',
];
foreach ( $args['options'] as $option => $attrs ) {
$checked = checked( $args['value'], $option, false );
$has_education = ! $is_pro && isset( $attrs['is_pro'] ) && $attrs['is_pro'];
$class = [ 'wpforms-settings-field-radio-wrapper', 'wpforms-card-image' ];
$datas = [];
// Add class and data attributes for education modal, if needed.
if ( $has_education ) {
$class[] = 'education-modal'; // This class is used for JS.
$datas = $education_args; // This data is used for JS.
}
$output .= '<span ' . wpforms_html_attributes( '', $class, $datas ) . '>';
$output .= '<input type="radio" id="wpforms-setting-' . $id . '[' . $x . ']" name="' . $id . '" value="' . esc_attr( $option ) . '" ' . $checked . '>';
$output .= '<label for="wpforms-setting-' . $id . '[' . $x . ']" class="option-' . sanitize_html_class( $option ) . '">';
$output .= esc_html( $attrs['name'] );
// Add class and data attributes for education modal, if needed.
if ( $has_education ) {
$output .= EducationHelpers::get_badge( 'Pro' );
}
$output .= '<span class="wpforms-card-image-overlay">';
$output .= '<span class="wpforms-btn-choose wpforms-btn wpforms-btn-md wpforms-btn-orange">';
$output .= esc_html__( 'Choose', 'wpforms-lite' ) . '</span>';
// Only add the preview action button if provided.
if ( ! empty( $attrs['preview'] ) ) {
$output .= '<a href="' . esc_url( $attrs['preview'] ) . '" class="wpforms-btn-preview wpforms-btn wpforms-btn-md wpforms-btn-light-grey" target="_blank">';
$output .= esc_html__( 'Preview', 'wpforms-lite' );
$output .= '</a>';
}
$output .= '</span>';
$output .= '</label>';
$output .= '</span>';
++$x;
}
if ( ! empty( $args['desc'] ) ) {
$output .= '<p class="desc">' . wp_kses_post( $args['desc'] ) . '</p>';
}
return $output;
}
/**
* Settings toggle field callback.
*
* @since 1.7.4
*
* @param array $args Arguments.
*
* @return string
*/
function wpforms_settings_toggle_callback( $args ) {
$value = wpforms_setting( $args['id'] );
$id = wpforms_sanitize_key( $args['id'] );
$class = ! empty( $args['control-class'] ) ? $args['control-class'] : '';
$class .= ! empty( $args['is-important'] ) ? ' wpforms-important' : '';
$input_attr = ! empty( $args['input-attr'] ) ? $args['input-attr'] : '';
$default_args = [
'control-class' => $class,
];
$args = wp_parse_args( $args, $default_args );
$output = wpforms_panel_field_toggle_control(
$args,
'wpforms-setting-' . $id,
$id,
! empty( $args['label'] ) ? $args['label'] : '',
$value,
$input_attr
);
$desc_on = ! empty( $args['desc'] ) ? $args['desc'] : '';
$desc_on = ! empty( $args['desc-on'] ) ? $args['desc-on'] : $desc_on;
$desc_off = ! empty( $args['desc-off'] ) ? $args['desc-off'] : '';
$output .= sprintf(
'<p class="desc desc-on wpforms-toggle-desc%1$s">%2$s</p>',
empty( $value ) && ! empty( $desc_off ) ? ' wpforms-hidden' : '',
wp_kses_post( $desc_on )
);
if ( ! empty( $desc_off ) ) {
$output .= sprintf(
'<p class="desc desc-off wpforms-toggle-desc%1$s">%2$s</p>',
empty( $value ) ? '' : ' wpforms-hidden',
wp_kses_post( $desc_off )
);
}
return $output;
}
/**
* Settings image upload field callback.
*
* @since 1.3.9
*
* @param array $args Arguments.
*
* @return string
*/
function wpforms_settings_image_callback( $args ) {
$default = isset( $args['default'] ) ? esc_html( $args['default'] ) : '';
$value = wpforms_setting( $args['id'], $default );
$id = wpforms_sanitize_key( $args['id'] );
$output = '';
if ( ! empty( $value ) ) {
$output .= '<img src="' . esc_url_raw( $value ) . '">';
}
$output .= '<input type="text" id="wpforms-setting-' . $id . '" name="' . $id . '" value="' . esc_url_raw( $value ) . '">';
// Show the remove button if specified.
if ( isset( $args['show_remove'] ) && $args['show_remove'] ) {
$output .= '<button class="wpforms-btn wpforms-btn-md wpforms-setting-remove-image">' . esc_html__( 'Remove Image', 'wpforms-lite' ) . '</button>';
}
$output .= '<button class="wpforms-btn wpforms-btn-md wpforms-btn-light-grey wpforms-setting-upload-image">' . esc_html__( 'Upload Image', 'wpforms-lite' ) . '</button>';
if ( ! empty( $args['desc'] ) ) {
$output .= '<p class="desc">' . wp_kses_post( $args['desc'] ) . '</p>';
}
return $output;
}
/**
* Settings color picker field callback.
*
* @since 1.3.9
*
* @param array $args
*
* @return string
*/
function wpforms_settings_color_callback( $args ) {
$default = isset( $args['default'] ) ? esc_html( $args['default'] ) : '';
$value = wpforms_setting( $args['id'], $default );
$id = wpforms_sanitize_key( $args['id'] );
$data = isset( $args['data'] ) ? (array) $args['data'] : [];
foreach ( $data as $name => $val ) {
$data[ $name ] = 'data-' . sanitize_html_class( $name ) . '="' . esc_attr( $val ) . '"';
}
$data = implode( ' ', $data );
$output = '<input type="text" id="wpforms-setting-' . $id . '" class="wpforms-color-picker" name="' . $id . '" value="' . esc_attr( $value ) . '" ' . $data . '>';
if ( ! empty( $args['desc'] ) ) {
$output .= '<p class="desc">' . wp_kses_post( $args['desc'] ) . '</p>';
}
return $output;
}
/**
* Color scheme endpoint fieldset callback.
* This function will output a fieldset with color picker inputs.
*
* @since 1.8.5
*
* @param array $args Field arguments.
*
* @return string
*/
function wpforms_settings_color_scheme_callback( $args ) {
$id = wpforms_sanitize_key( $args['id'] );
$value = wpforms_setting( $args['id'], [] );
$output = '';
foreach ( $args['colors'] as $color => $attrs ) {
$data = isset( $attrs['data'] ) ? (array) $attrs['data'] : [];
$default_value = isset( $data['fallback-color'] ) ? wpforms_sanitize_hex_color( $data['fallback-color'] ) : '';
$field_id = "{$id}-{$color}";
$field_value = isset( $value[ $color ] ) ? wpforms_sanitize_hex_color( $value[ $color ] ) : $default_value;
$input_attributes = wpforms_html_attributes(
"wpforms-setting-{$field_id}",
[ 'wpforms-color-picker' ],
$data,
[
'type' => 'text',
'name' => "{$id}[{$color}]",
'value' => esc_attr( $field_value ),
]
);
$output .= "<input {$input_attributes}>";
$output .= '<label for="wpforms-setting-' . $field_id . '">';
$output .= esc_html( $attrs['name'] );
$output .= '</label>';
}
if ( ! empty( $args['desc'] ) ) {
$output .= '<p class="desc">' . wp_kses_post( $args['desc'] ) . '</p>';
}
return $output;
}
/**
* Settings providers field callback - this is for the Integrations tab.
*
* @since 1.3.9
*
* @param array $args
*
* @return string
*/
function wpforms_settings_providers_callback( $args ) {
$active = wpforms_get_providers_available();
$providers = wpforms_get_providers_options();
$output = '<div id="wpforms-settings-providers">';
ob_start();
do_action( 'wpforms_settings_providers', $active, $providers );
$output .= ob_get_clean();
$output .= '</div>';
return $output;
}
/**
* Webhooks' endpoint field callback.
*
* @since 1.8.4
*
* @param array $args Field arguments.
*
* @return string
*/
function wpforms_settings_webhook_endpoint_callback( $args ) {
$output = '';
if ( ! empty( $args['url'] ) ) {
$output = '<div class="wpforms-stripe-webhook-endpoint-url">';
$output .= '<input type="text" disabled id="wpforms-stripe-webhook-endpoint-url" value="' . esc_url_raw( $args['url'] ) . '" />';
$output .= '<a class="button button-secondary wpforms-copy-to-clipboard" data-clipboard-target="#wpforms-stripe-webhook-endpoint-url" href="" ><span class="dashicons dashicons-admin-page"></span></a>';
$output .= '</div>';
if ( ! empty( $args['desc'] ) ) {
$output .= '<p class="desc">' . wp_kses_post( $args['desc'] ) . '</p>';
}
}
return $output;
}
/**
* Settings field columns callback.
*
* @since 1.5.8
*
* @param array $args Arguments passed by the setting.
*
* @return string
*/
function wpforms_settings_columns_callback( $args ) {
if ( empty( $args['columns'] ) || ! is_array( $args['columns'] ) ) {
return '';
}
$output = '<div class="wpforms-setting-columns">';
foreach ( $args['columns'] as $column ) {
// Define default callback for this field type.
$callback = ! empty( $column['type'] ) ? 'wpforms_settings_' . $column['type'] . '_callback' : '';
// Allow custom callback to be provided via arg.
if ( ! empty( $column['callback'] ) ) {
$callback = $column['callback'];
}
$output .= '<div class="wpforms-setting-column">';
if ( ! empty( $column['name'] ) ) {
$output .= '<label><b>' . wp_kses_post( $column['name'] ) . '</b></label>';
}
if ( function_exists( $callback ) ) {
$output .= call_user_func( $callback, $column );
}
$output .= '</div>';
}
$output .= '</div>';
return $output;
}