Initial commit: WordPress wp-content (themes, plugins, languages)
- Theme: momentry (custom theme with REST API routes) - Plugins: code-snippets (contains all API proxies) - Languages: zh_TW translations - Excludes: cache, backups, uploads, logs
This commit is contained in:
@@ -0,0 +1,288 @@
|
||||
<?php
|
||||
|
||||
namespace WPForms\Lite\Admin;
|
||||
|
||||
use WP_Error;
|
||||
use WPForms\Helpers\PluginSilentUpgrader;
|
||||
|
||||
/**
|
||||
* WPForms Connect.
|
||||
*
|
||||
* WPForms Connect is our service that makes it easy for non-techy users to
|
||||
* upgrade to WPForms Pro without having to manually install WPForms Pro plugin.
|
||||
*
|
||||
* @since 1.5.5
|
||||
*/
|
||||
class Connect {
|
||||
|
||||
/**
|
||||
* WPForms Pro plugin basename.
|
||||
*
|
||||
* @since 1.8.4
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const PRO_PLUGIN = 'wpforms/wpforms.php';
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @since 1.5.5
|
||||
*/
|
||||
public function __construct() {
|
||||
|
||||
$this->hooks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hooks.
|
||||
*
|
||||
* @since 1.5.5
|
||||
*/
|
||||
public function hooks() {
|
||||
|
||||
add_action( 'wpforms_settings_enqueue', [ $this, 'settings_enqueues' ] );
|
||||
add_action( 'wp_ajax_wpforms_connect_url', [ $this, 'generate_url' ] );
|
||||
add_action( 'wp_ajax_nopriv_wpforms_connect_process', [ $this, 'process' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Settings page enqueues.
|
||||
*
|
||||
* @since 1.5.5
|
||||
*/
|
||||
public function settings_enqueues() {
|
||||
|
||||
$min = wpforms_get_min_suffix();
|
||||
|
||||
wp_enqueue_script(
|
||||
'wpforms-connect',
|
||||
WPFORMS_PLUGIN_URL . "assets/lite/js/admin/connect{$min}.js",
|
||||
[ 'jquery' ],
|
||||
WPFORMS_VERSION,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate and return WPForms Connect URL.
|
||||
*
|
||||
* @since 1.5.5
|
||||
*/
|
||||
public function generate_url() {
|
||||
|
||||
// Run a security check.
|
||||
check_ajax_referer( 'wpforms-admin', 'nonce' );
|
||||
|
||||
// Check for permissions.
|
||||
if ( ! current_user_can( 'install_plugins' ) ) {
|
||||
wp_send_json_error( [ 'message' => esc_html__( 'You are not allowed to install plugins.', 'wpforms-lite' ) ] );
|
||||
}
|
||||
|
||||
$current_plugin = plugin_basename( WPFORMS_PLUGIN_FILE );
|
||||
$is_pro = wpforms()->is_pro();
|
||||
|
||||
// Local development environment.
|
||||
if ( $current_plugin === self::PRO_PLUGIN && ! $is_pro ) {
|
||||
wp_send_json_error( [ 'message' => esc_html__( 'There must be a non-developer Lite version installed to upgrade.', 'wpforms-lite' ) ] );
|
||||
}
|
||||
|
||||
$key = ! empty( $_POST['key'] ) ? sanitize_text_field( wp_unslash( $_POST['key'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification
|
||||
|
||||
// Empty license key.
|
||||
if ( empty( $key ) ) {
|
||||
wp_send_json_error( [ 'message' => esc_html__( 'Please enter your license key to connect.', 'wpforms-lite' ) ] );
|
||||
}
|
||||
|
||||
// Whether it is the pro version.
|
||||
if ( $is_pro ) {
|
||||
wp_send_json_error( [ 'message' => esc_html__( 'Only the Lite version can be upgraded.', 'wpforms-lite' ) ] );
|
||||
}
|
||||
|
||||
// Verify pro version is not installed.
|
||||
$active = activate_plugin( self::PRO_PLUGIN, false, false, true );
|
||||
|
||||
if ( ! is_wp_error( $active ) ) {
|
||||
|
||||
// Deactivate Lite.
|
||||
deactivate_plugins( $current_plugin );
|
||||
|
||||
// phpcs:ignore WPForms.Comments.PHPDocHooks.RequiredHookDocumentation, WPForms.PHP.ValidateHooks.InvalidHookName
|
||||
do_action( 'wpforms_plugin_deactivated', $current_plugin );
|
||||
|
||||
wp_send_json_success(
|
||||
[
|
||||
'message' => esc_html__( 'WPForms Pro is installed but not activated.', 'wpforms-lite' ),
|
||||
'reload' => true,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
// Generate URL.
|
||||
$oth = hash( 'sha512', wp_rand() );
|
||||
$hashed_oth = hash_hmac( 'sha512', $oth, wp_salt() );
|
||||
|
||||
update_option( 'wpforms_connect_token', $oth );
|
||||
update_option( 'wpforms_connect', $key );
|
||||
|
||||
$version = WPFORMS_VERSION;
|
||||
$endpoint = admin_url( 'admin-ajax.php' );
|
||||
$redirect = admin_url( 'admin.php?page=wpforms-settings' );
|
||||
$url = add_query_arg(
|
||||
[
|
||||
'key' => $key,
|
||||
'oth' => $hashed_oth,
|
||||
'endpoint' => $endpoint,
|
||||
'version' => $version,
|
||||
'siteurl' => admin_url(),
|
||||
'homeurl' => site_url(),
|
||||
'redirect' => rawurldecode( base64_encode( $redirect ) ), // phpcs:ignore
|
||||
'v' => 2,
|
||||
],
|
||||
'https://upgrade.wpforms.com'
|
||||
);
|
||||
|
||||
wp_send_json_success(
|
||||
[
|
||||
'url' => $url,
|
||||
'back_url' => add_query_arg(
|
||||
[
|
||||
'action' => 'wpforms_connect',
|
||||
'oth' => $hashed_oth,
|
||||
],
|
||||
$endpoint
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process WPForms Connect.
|
||||
*
|
||||
* @since 1.5.5
|
||||
*/
|
||||
public function process() { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh, WPForms.PHP.HooksMethod.InvalidPlaceForAddingHooks
|
||||
|
||||
$error = esc_html__( 'There was an error while installing an upgrade. Please download the plugin from wpforms.com and install it manually.', 'wpforms-lite' );
|
||||
|
||||
// Verify params present (oth & download link).
|
||||
$post_oth = ! empty( $_REQUEST['oth'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['oth'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification
|
||||
$post_url = ! empty( $_REQUEST['file'] ) ? esc_url_raw( wp_unslash( $_REQUEST['file'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification
|
||||
|
||||
if ( empty( $post_oth ) || empty( $post_url ) ) {
|
||||
wp_send_json_error( $error );
|
||||
}
|
||||
|
||||
// Verify oth.
|
||||
$oth = get_option( 'wpforms_connect_token' );
|
||||
|
||||
if ( empty( $oth ) ) {
|
||||
wp_send_json_error( $error );
|
||||
}
|
||||
|
||||
if ( hash_hmac( 'sha512', $oth, wp_salt() ) !== $post_oth ) {
|
||||
wp_send_json_error( $error );
|
||||
}
|
||||
|
||||
// Delete so cannot replay.
|
||||
delete_option( 'wpforms_connect_token' );
|
||||
|
||||
// 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-settings' ],
|
||||
admin_url( 'admin.php' )
|
||||
)
|
||||
);
|
||||
|
||||
// Verify pro not activated.
|
||||
if ( wpforms()->is_pro() ) {
|
||||
wp_send_json_success( esc_html__( 'Plugin installed & activated.', 'wpforms-lite' ) );
|
||||
}
|
||||
|
||||
// Verify pro not installed.
|
||||
$active = activate_plugin( self::PRO_PLUGIN, $url, false, true );
|
||||
|
||||
if ( ! is_wp_error( $active ) ) {
|
||||
$plugin = plugin_basename( WPFORMS_PLUGIN_FILE );
|
||||
|
||||
deactivate_plugins( $plugin );
|
||||
|
||||
// phpcs:ignore WPForms.Comments.PHPDocHooks.RequiredHookDocumentation, WPForms.PHP.ValidateHooks.InvalidHookName
|
||||
do_action( 'wpforms_plugin_deactivated', $plugin );
|
||||
|
||||
wp_send_json_success( esc_html__( 'Plugin installed & activated.', 'wpforms-lite' ) );
|
||||
}
|
||||
|
||||
$creds = request_filesystem_credentials( $url, '', false, false );
|
||||
|
||||
// Check for file system permissions.
|
||||
if ( $creds === false || ! WP_Filesystem( $creds ) ) {
|
||||
wp_send_json_error(
|
||||
esc_html__( 'There was an error while installing an upgrade. Please check file system permissions and try again. Also, you can download the plugin from wpforms.com and install it manually.', 'wpforms-lite' )
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* We do not need any extra credentials if we have gotten this far, so let's install the plugin.
|
||||
*/
|
||||
|
||||
// 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 PluginSilentUpgrader( new ConnectSkin() );
|
||||
|
||||
// Error check.
|
||||
if ( ! method_exists( $installer, 'install' ) ) {
|
||||
wp_send_json_error( $error );
|
||||
}
|
||||
|
||||
// Check license key.
|
||||
$key = get_option( 'wpforms_connect', false );
|
||||
|
||||
if ( empty( $key ) ) {
|
||||
wp_send_json_error(
|
||||
new WP_Error(
|
||||
'403',
|
||||
esc_html__( 'No key provided.', 'wpforms-lite' )
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$installer->install( $post_url ); // phpcs:ignore
|
||||
|
||||
// Flush the cache and return the newly installed plugin basename.
|
||||
wp_cache_flush();
|
||||
|
||||
$plugin_basename = $installer->plugin_info();
|
||||
|
||||
if ( $plugin_basename ) {
|
||||
|
||||
// Deactivate the lite version first.
|
||||
$plugin = plugin_basename( WPFORMS_PLUGIN_FILE );
|
||||
|
||||
deactivate_plugins( $plugin );
|
||||
|
||||
// phpcs:ignore WPForms.Comments.PHPDocHooks.RequiredHookDocumentation, WPForms.PHP.ValidateHooks.InvalidHookName
|
||||
do_action( 'wpforms_plugin_deactivated', $plugin );
|
||||
|
||||
// Activate the plugin silently.
|
||||
$activated = activate_plugin( $plugin_basename, '', false, true );
|
||||
|
||||
if ( ! is_wp_error( $activated ) ) {
|
||||
add_option( 'wpforms_install', 1 );
|
||||
wp_send_json_success( esc_html__( 'Plugin installed & activated.', 'wpforms-lite' ) );
|
||||
} else {
|
||||
// Reactivate the lite plugin if pro activation failed.
|
||||
activate_plugin( plugin_basename( WPFORMS_PLUGIN_FILE ), '', false, true );
|
||||
wp_send_json_error( esc_html__( 'Pro version installed but needs to be activated on the Plugins page inside your WordPress admin.', 'wpforms-lite' ) );
|
||||
}
|
||||
}
|
||||
|
||||
wp_send_json_error( $error );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace WPForms\Lite\Admin;
|
||||
|
||||
use WP_Ajax_Upgrader_Skin;
|
||||
use WP_Error; // phpcs:ignore WPForms.PHP.UseStatement.UnusedUseStatement
|
||||
|
||||
/**
|
||||
* WPForms Connect Skin.
|
||||
*
|
||||
* WPForms Connect is our service that makes it easy for non-techy users to
|
||||
* upgrade to WPForms Pro without having to manually install WPForms Pro plugin.
|
||||
*
|
||||
* @since 1.5.5
|
||||
* @since 1.5.6.1 Extend PluginSilentUpgraderSkin and clean up the class.
|
||||
* @since 1.9.5 Extend WP_Ajax_Upgrader_Skin class.
|
||||
*/
|
||||
class ConnectSkin extends WP_Ajax_Upgrader_Skin {
|
||||
|
||||
/**
|
||||
* Instead of outputting HTML for errors, json_encode the errors and send them
|
||||
* back to the Ajax script for processing.
|
||||
*
|
||||
* @since 1.5.5
|
||||
*
|
||||
* @param string|WP_Error $errors Errors.
|
||||
* @param mixed ...$args Optional text replacements.
|
||||
*/
|
||||
public function error( $errors, ...$args ) {
|
||||
|
||||
if ( ! empty( $errors ) ) {
|
||||
wp_send_json_error( esc_html__( 'There was an error installing WPForms Pro. Please try again.', 'wpforms-lite' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,583 @@
|
||||
<?php
|
||||
|
||||
namespace WPForms\Lite\Admin;
|
||||
|
||||
use WPForms\Admin\Blocks\Links;
|
||||
use WPForms\Admin\Dashboard\Widget;
|
||||
|
||||
/**
|
||||
* Dashboard Widget shows a chart and the form entries stats in WP Dashboard.
|
||||
*
|
||||
* @since 1.5.0
|
||||
*/
|
||||
class DashboardWidget extends Widget {
|
||||
|
||||
/**
|
||||
* Widget settings.
|
||||
*
|
||||
* @since 1.5.0
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $settings;
|
||||
|
||||
/**
|
||||
* Init class.
|
||||
*
|
||||
* @since 1.5.5
|
||||
*/
|
||||
public function init() { // phpcs:ignore WPForms.PHP.HooksMethod.InvalidPlaceForAddingHooks
|
||||
|
||||
// phpcs:disable WPForms.PHP.ValidateHooks.InvalidHookName
|
||||
/**
|
||||
* Allow disabling the widget.
|
||||
*
|
||||
* @since 1.5.1
|
||||
*
|
||||
* @param bool $load Should the widget be loaded?
|
||||
*/
|
||||
if ( ! apply_filters( 'wpforms_admin_dashboardwidget', true ) ) {
|
||||
return;
|
||||
}
|
||||
// phpcs:enable WPForms.PHP.ValidateHooks.InvalidHookName
|
||||
|
||||
add_action( 'wpforms_process_complete', [ static::class, 'clear_widget_cache' ] );
|
||||
add_action( 'admin_init', [ $this, 'admin_init' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Admin init class.
|
||||
*
|
||||
* @since 1.8.3
|
||||
*/
|
||||
public function admin_init() { // phpcs:ignore WPForms.PHP.HooksMethod.InvalidPlaceForAddingHooks
|
||||
|
||||
// This widget should be displayed for certain high-level users only.
|
||||
if ( ! wpforms_current_user_can( 'view_forms' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
add_action( 'wpforms_create_form', [ static::class, 'clear_widget_cache' ] );
|
||||
add_action( 'wpforms_save_form', [ static::class, 'clear_widget_cache' ] );
|
||||
add_action( 'wpforms_delete_form', [ static::class, 'clear_widget_cache' ] );
|
||||
|
||||
/**
|
||||
* Clear cache after Lite plugin deactivation.
|
||||
*
|
||||
* Also triggered when the user upgrades the plugin to the Pro version.
|
||||
* After activation of the Pro version, the cache will be cleared.
|
||||
*/
|
||||
add_action( 'deactivate_wpforms-lite/wpforms.php', [ static::class, 'clear_widget_cache' ] );
|
||||
|
||||
if ( ! $this->is_dashboard_page() && ! $this->is_dashboard_widget_ajax_request() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->settings();
|
||||
$this->hooks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Filterable widget settings.
|
||||
*
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public function settings() {
|
||||
|
||||
// phpcs:disable WPForms.Comments.PHPDocHooks.RequiredHookDocumentation, WPForms.PHP.ValidateHooks.InvalidHookName
|
||||
|
||||
$this->settings = [
|
||||
|
||||
// Number of forms to display in the forms' list before the "Show More" button appears.
|
||||
'forms_list_number_to_display' => apply_filters( 'wpforms_dash_widget_forms_list_number_to_display', 5 ),
|
||||
|
||||
// Allow results caching to reduce a DB load.
|
||||
'allow_data_caching' => apply_filters( 'wpforms_dash_widget_allow_data_caching', true ),
|
||||
|
||||
// Transient lifetime in seconds. Defaults to the end of a current day.
|
||||
'transient_lifetime' => apply_filters( 'wpforms_dash_widget_transient_lifetime', strtotime( 'tomorrow' ) - time() ),
|
||||
|
||||
// Determine if the forms with no entries should appear in a forms' list.
|
||||
// Once switched, the effect applies after cache expiration.
|
||||
'display_forms_list_empty_entries' => apply_filters( 'wpforms_dash_widget_display_forms_list_empty_entries', true ),
|
||||
];
|
||||
|
||||
// phpcs:enable WPForms.Comments.PHPDocHooks.RequiredHookDocumentation, WPForms.PHP.ValidateHooks.InvalidHookName
|
||||
}
|
||||
|
||||
/**
|
||||
* Widget hooks.
|
||||
*
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public function hooks() {
|
||||
|
||||
$widget_slug = static::SLUG;
|
||||
|
||||
add_action( 'admin_enqueue_scripts', [ $this, 'widget_scripts' ] );
|
||||
add_action( 'wp_dashboard_setup', [ $this, 'widget_register' ] );
|
||||
add_action( 'admin_init', [ $this, 'hide_widget' ] );
|
||||
add_action( "wp_ajax_wpforms_{$widget_slug}_save_widget_meta", [ $this, 'save_widget_meta_ajax' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Load widget-specific scripts.
|
||||
*
|
||||
* @since 1.5.0
|
||||
*
|
||||
* @param string $hook_suffix The current admin page.
|
||||
*/
|
||||
public function widget_scripts( $hook_suffix ) {
|
||||
|
||||
if ( $hook_suffix !== 'index.php' ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$min = wpforms_get_min_suffix();
|
||||
|
||||
wp_enqueue_style(
|
||||
'wpforms-dashboard-widget',
|
||||
WPFORMS_PLUGIN_URL . "assets/css/dashboard-widget{$min}.css",
|
||||
[],
|
||||
WPFORMS_VERSION
|
||||
);
|
||||
|
||||
wp_enqueue_script(
|
||||
'wpforms-chart',
|
||||
WPFORMS_PLUGIN_URL . 'assets/lib/chart.min.js',
|
||||
[ 'moment' ],
|
||||
'4.5.1',
|
||||
true
|
||||
);
|
||||
|
||||
wp_enqueue_script(
|
||||
'wpforms-dashboard-widget',
|
||||
WPFORMS_PLUGIN_URL . "assets/lite/js/admin/dashboard-widget{$min}.js",
|
||||
[ 'jquery', 'wpforms-chart' ],
|
||||
WPFORMS_VERSION,
|
||||
true
|
||||
);
|
||||
|
||||
wp_localize_script(
|
||||
'wpforms-dashboard-widget',
|
||||
'wpforms_dashboard_widget',
|
||||
[
|
||||
'nonce' => wp_create_nonce( 'wpforms_' . static::SLUG . '_nonce' ),
|
||||
'slug' => static::SLUG,
|
||||
'show_more_html' => esc_html__( 'Show More', 'wpforms-lite' ) . '<span class="dashicons dashicons-arrow-down"></span>',
|
||||
'show_less_html' => esc_html__( 'Show Less', 'wpforms-lite' ) . '<span class="dashicons dashicons-arrow-up"></span>',
|
||||
'i18n' => [
|
||||
'entries' => esc_html__( 'Entries', 'wpforms-lite' ),
|
||||
],
|
||||
// Adapter for Chart.js to use Moment.js for date formatting.
|
||||
'adapter_path' => WPFORMS_PLUGIN_URL . 'assets/lib/chartjs-adapter-moment.min.js?ver=1.0.1',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the widget.
|
||||
*
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public function widget_register() {
|
||||
|
||||
global $wp_meta_boxes;
|
||||
|
||||
$widget_key = 'wpforms_reports_widget_lite';
|
||||
|
||||
wp_add_dashboard_widget(
|
||||
$widget_key,
|
||||
esc_html__( 'WPForms', 'wpforms-lite' ),
|
||||
[ $this, 'widget_content' ]
|
||||
);
|
||||
|
||||
// Attempt to place the widget at the top.
|
||||
$normal_dashboard = $wp_meta_boxes['dashboard']['normal']['core'];
|
||||
$widget_instance = [ $widget_key => $normal_dashboard[ $widget_key ] ];
|
||||
|
||||
unset( $normal_dashboard[ $widget_key ] );
|
||||
|
||||
$sorted_dashboard = array_merge( $widget_instance, $normal_dashboard );
|
||||
|
||||
// phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
|
||||
$wp_meta_boxes['dashboard']['normal']['core'] = $sorted_dashboard;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load widget content.
|
||||
*
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public function widget_content() {
|
||||
|
||||
$forms = wpforms()->obj( 'form' )->get( '', [ 'fields' => 'ids' ] );
|
||||
$hide_graph = (bool) $this->widget_meta( 'get', 'hide_graph' );
|
||||
$no_graph_class = $hide_graph ? 'wpforms-dash-widget-no-graph' : '';
|
||||
|
||||
echo '<div class="wpforms-dash-widget wpforms-lite ' . esc_attr( $no_graph_class ) . '">';
|
||||
|
||||
if ( empty( $forms ) ) {
|
||||
$this->widget_content_no_forms_html();
|
||||
} else {
|
||||
$this->widget_content_html( $hide_graph );
|
||||
}
|
||||
|
||||
Links::render(
|
||||
[
|
||||
'docs' => [
|
||||
'medium' => 'dashboard-widget',
|
||||
'content' => 'docs',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$plugin = $this->get_recommended_plugin();
|
||||
$hide_recommended = $this->widget_meta( 'get', 'hide_recommended_block' );
|
||||
|
||||
if (
|
||||
! empty( $plugin ) &&
|
||||
! empty( $forms ) &&
|
||||
! $hide_recommended
|
||||
) {
|
||||
$this->recommended_plugin_block_html( $plugin );
|
||||
}
|
||||
|
||||
echo '</div><!-- .wpforms-dash-widget -->';
|
||||
}
|
||||
|
||||
/**
|
||||
* Widget content HTML if a user has no forms.
|
||||
*
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public function widget_content_no_forms_html() {
|
||||
|
||||
$create_form_url = add_query_arg( 'page', 'wpforms-builder', admin_url( 'admin.php' ) );
|
||||
$learn_more_url = 'https://wpforms.com/docs/creating-first-form/?utm_source=WordPress&utm_medium=link&utm_campaign=liteplugin&utm_content=dashboardwidget';
|
||||
|
||||
?>
|
||||
<div class="wpforms-dash-widget-block wpforms-dash-widget-block-no-forms">
|
||||
<img class="wpforms-dash-widget-block-sullie-logo" src="<?php echo esc_url( WPFORMS_PLUGIN_URL . 'assets/images/sullie.png' ); ?>" alt="<?php esc_attr_e( 'Sullie the WPForms mascot', 'wpforms-lite' ); ?>">
|
||||
<h2><?php esc_html_e( 'Create Your First Form to Start Collecting Leads', 'wpforms-lite' ); ?></h2>
|
||||
<p><?php esc_html_e( 'You can use WPForms to build contact forms, surveys, payment forms, and more with just a few clicks.', 'wpforms-lite' ); ?></p>
|
||||
|
||||
<?php if ( wpforms_current_user_can( 'create_forms' ) ) : ?>
|
||||
<a href="<?php echo esc_url( $create_form_url ); ?>" class="button button-primary">
|
||||
<?php esc_html_e( 'Create Your Form', 'wpforms-lite' ); ?>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
|
||||
<a href="<?php echo esc_url( $learn_more_url ); ?>" class="button" target="_blank" rel="noopener noreferrer">
|
||||
<?php esc_html_e( 'Learn More', 'wpforms-lite' ); ?>
|
||||
</a>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Widget content HTML.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @since 1.7.4 Added hide graph parameter.
|
||||
*
|
||||
* @param bool $hide_graph Whether the graph is hidden.
|
||||
*/
|
||||
public function widget_content_html( $hide_graph = false ) {
|
||||
|
||||
// phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
/**
|
||||
* Filters the content before the Dashboard Widget Chart block container (for Lite).
|
||||
*
|
||||
* @since 1.7.4
|
||||
*
|
||||
* @param string $chart_block_before Chart block before markup.
|
||||
*/
|
||||
echo apply_filters( 'wpforms_lite_admin_dashboard_widget_content_html_chart_block_before', '' );
|
||||
// phpcs:enable WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
|
||||
if ( ! $hide_graph ) :
|
||||
?>
|
||||
|
||||
<div class="wpforms-dash-widget-chart-block-container">
|
||||
|
||||
<div class="wpforms-dash-widget-block wpforms-dash-widget-chart-block">
|
||||
<canvas id="wpforms-dash-widget-chart" width="400" height="300"></canvas>
|
||||
</div>
|
||||
|
||||
<div class="wpforms-dash-widget-block-upgrade">
|
||||
<div class="wpforms-dash-widget-modal">
|
||||
<a href="#" class="wpforms-dash-widget-dismiss-chart-upgrade">
|
||||
<span class="dashicons dashicons-no-alt"></span>
|
||||
</a>
|
||||
<h2><?php esc_html_e( 'View all Form Entries inside the WordPress Dashboard', 'wpforms-lite' ); ?></h2>
|
||||
<p><?php esc_html_e( 'Form entries reports are not available.', 'wpforms-lite' ); ?>
|
||||
<?php esc_html_e( 'Form entries are not stored in Lite.', 'wpforms-lite' ); ?>
|
||||
<?php esc_html_e( 'Upgrade to Pro and get access to the reports.', 'wpforms-lite' ); ?></p>
|
||||
<p>
|
||||
<a href="<?php echo esc_url( wpforms_admin_upgrade_link( 'dashboard-widget', 'upgrade-to-pro' ) ); ?>" class="wpforms-dash-widget-upgrade-btn" target="_blank" rel="noopener noreferrer">
|
||||
<?php esc_html_e( 'Upgrade to WPForms Pro', 'wpforms-lite' ); ?>
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="wpforms-dash-widget-block wpforms-dash-widget-block-title">
|
||||
<h3><?php esc_html_e( 'Total Entries by Form', 'wpforms-lite' ); ?></h3>
|
||||
<div class="wpforms-dash-widget-settings">
|
||||
<?php
|
||||
$this->timespan_select_html( 0, false );
|
||||
$this->widget_settings_html( false );
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="wpforms-dash-widget-forms-list-block" class="wpforms-dash-widget-block wpforms-dash-widget-forms-list-block">
|
||||
<?php $this->forms_list_block(); ?>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Forms list block.
|
||||
*
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public function forms_list_block() {
|
||||
|
||||
$forms = $this->get_entries_count_by_form();
|
||||
|
||||
if ( empty( $forms ) ) {
|
||||
$this->forms_list_block_empty_html();
|
||||
} else {
|
||||
$this->forms_list_block_html( $forms );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty forms list block HTML.
|
||||
*
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public function forms_list_block_empty_html() {
|
||||
|
||||
?>
|
||||
<p class="wpforms-error wpforms-error-no-data-forms-list">
|
||||
<?php esc_html_e( 'No entries were submitted yet.', 'wpforms-lite' ); ?>
|
||||
</p>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Forms list block HTML.
|
||||
*
|
||||
* @since 1.5.0
|
||||
*
|
||||
* @param array $forms Forms to display in the list.
|
||||
*/
|
||||
public function forms_list_block_html( $forms ) {
|
||||
|
||||
// Number of forms to display in the forms' list before the "Show More" button appears.
|
||||
$show_forms = $this->settings['forms_list_number_to_display'];
|
||||
|
||||
?>
|
||||
<table id="wpforms-dash-widget-forms-list-table" cellspacing="0">
|
||||
<?php foreach ( array_values( $forms ) as $key => $form ) : ?>
|
||||
<tr <?php echo $key >= $show_forms ? 'class="wpforms-dash-widget-forms-list-hidden-el"' : ''; ?> data-form-id="<?php echo absint( $form['form_id'] ); ?>">
|
||||
<td><span class="wpforms-dash-widget-form-title"><?php echo esc_html( $form['title'] ); ?></span></td>
|
||||
<td><?php echo absint( $form['count'] ); ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</table>
|
||||
|
||||
<?php if ( count( $forms ) > $show_forms ) : ?>
|
||||
<button type="button" id="wpforms-dash-widget-forms-more" class="wpforms-dash-widget-forms-more" title="<?php esc_html_e( 'Show all forms', 'wpforms-lite' ); ?>">
|
||||
<?php esc_html_e( 'Show More', 'wpforms-lite' ); ?> <span class="dashicons dashicons-arrow-down"></span>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Recommended plugin block HTML.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @since 1.7.3 Added plugin parameter.
|
||||
*
|
||||
* @param array $plugin Plugin data.
|
||||
*/
|
||||
public function recommended_plugin_block_html( $plugin = [] ) {
|
||||
|
||||
if ( ! $plugin ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$install_url = wp_nonce_url(
|
||||
self_admin_url( 'update.php?action=install-plugin&plugin=' . rawurlencode( $plugin['slug'] ) ),
|
||||
'install-plugin_' . $plugin['slug']
|
||||
);
|
||||
|
||||
?>
|
||||
<div class="wpforms-dash-widget-block wpforms-dash-widget-recommended-plugin-block">
|
||||
<span class="wpforms-dash-widget-recommended-plugin">
|
||||
<span class="recommended"><?php esc_html_e( 'Recommended Plugin:', 'wpforms-lite' ); ?></span>
|
||||
<strong><?php echo esc_html( $plugin['name'] ); ?></strong>
|
||||
<span class="sep">-</span>
|
||||
<span class="action-links">
|
||||
<?php if ( wpforms_can_install( 'plugin' ) ) { ?>
|
||||
<a href="<?php echo esc_url( $install_url ); ?>"><?php esc_html_e( 'Install', 'wpforms-lite' ); ?></a>
|
||||
<span class="sep sep-vertical">|</span>
|
||||
<?php } ?>
|
||||
<a href="<?php echo esc_url( $plugin['more'] ); ?>?utm_source=wpformsplugin&utm_medium=link&utm_campaign=wpformsdashboardwidget"><?php esc_html_e( 'Learn More', 'wpforms-lite' ); ?></a>
|
||||
</span>
|
||||
</span>
|
||||
<button type="button" class="wpforms-dash-widget-dismiss-icon" title="<?php esc_html_e( 'Dismiss', 'wpforms-lite' ); ?>" data-field="hide_recommended_block">
|
||||
<span class="dashicons dashicons-no-alt"></span>
|
||||
</button>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* The welcome block HTML.
|
||||
*
|
||||
* @since 1.8.7
|
||||
* @deprecated 1.9.7
|
||||
*/
|
||||
public function welcome_block_html() {
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get entries count grouped by form.
|
||||
* Main point of entry to fetch form entry count data from DB.
|
||||
* Cache the result.
|
||||
*
|
||||
* @since 1.5.0
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_entries_count_by_form(): array {
|
||||
|
||||
// Allow results caching to reduce a DB load.
|
||||
$allow_caching = $this->settings['allow_data_caching'];
|
||||
$transient_name = 'wpforms_dash_widget_lite_entries_by_form';
|
||||
|
||||
if ( $allow_caching ) {
|
||||
$cache = get_transient( $transient_name );
|
||||
|
||||
/**
|
||||
* Filters the cache to clear or alter its data.
|
||||
*
|
||||
* @since 1.5.0
|
||||
*
|
||||
* @param mixed $cache The cache content.
|
||||
*/
|
||||
$cache = apply_filters( 'wpforms_dash_widget_lite_cached_data', $cache ); // phpcs:ignore WPForms.PHP.ValidateHooks.InvalidHookName
|
||||
}
|
||||
|
||||
// is_array() detects cached empty searches.
|
||||
if ( $allow_caching && is_array( $cache ) ) {
|
||||
return $cache;
|
||||
}
|
||||
|
||||
$forms = wpforms()->obj( 'form' )->get( '', [ 'fields' => 'ids' ] );
|
||||
|
||||
if ( empty( $forms ) || ! is_array( $forms ) ) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$result = [];
|
||||
|
||||
foreach ( $forms as $form_id ) {
|
||||
$count = absint( get_post_meta( $form_id, 'wpforms_entries_count', true ) );
|
||||
|
||||
if ( empty( $count ) && empty( $this->settings['display_forms_list_empty_entries'] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$result[ $form_id ] = [
|
||||
'form_id' => $form_id,
|
||||
'count' => $count,
|
||||
'title' => get_the_title( $form_id ),
|
||||
];
|
||||
}
|
||||
|
||||
if ( ! empty( $result ) ) {
|
||||
// Sort forms by entries count (desc).
|
||||
uasort(
|
||||
$result,
|
||||
static function ( $a, $b ) {
|
||||
|
||||
return ( $a['count'] > $b['count'] ) ? -1 : 1;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if ( $allow_caching ) {
|
||||
// Transient lifetime in seconds. Defaults to the end of a current day.
|
||||
$transient_lifetime = $this->settings['transient_lifetime'];
|
||||
|
||||
set_transient( $transient_name, $result, $transient_lifetime );
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide dashboard widget.
|
||||
* Use dashboard screen options to make it visible again.
|
||||
*
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public function hide_widget() {
|
||||
|
||||
if ( ! is_admin() || ! is_user_logged_in() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! isset( $_GET['wpforms-nonce'] ) || ! wp_verify_nonce( sanitize_key( wp_unslash( $_GET['wpforms-nonce'] ) ), 'wpforms_hide_dash_widget' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! isset( $_GET['wpforms-widget'] ) || $_GET['wpforms-widget'] !== 'hide' ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$user_id = get_current_user_id();
|
||||
$metaboxhidden = get_user_meta( $user_id, 'metaboxhidden_dashboard', true );
|
||||
|
||||
if ( ! is_array( $metaboxhidden ) ) {
|
||||
update_user_meta( $user_id, 'metaboxhidden_dashboard', [ 'wpforms_reports_widget_lite' ] );
|
||||
}
|
||||
|
||||
if ( is_array( $metaboxhidden ) && ! in_array( 'wpforms_reports_widget_lite', $metaboxhidden, true ) ) {
|
||||
$metaboxhidden[] = 'wpforms_reports_widget_lite';
|
||||
|
||||
update_user_meta( $user_id, 'metaboxhidden_dashboard', $metaboxhidden );
|
||||
}
|
||||
|
||||
$redirect_url = remove_query_arg( [ 'wpforms-widget', 'wpforms-nonce' ] );
|
||||
|
||||
wp_safe_redirect( $redirect_url );
|
||||
exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear dashboard widget cached data.
|
||||
*
|
||||
* @since 1.5.2
|
||||
*/
|
||||
public static function clear_widget_cache() {
|
||||
|
||||
delete_transient( 'wpforms_dash_widget_lite_entries_by_form' );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
<?php
|
||||
|
||||
namespace WPForms\Lite\Admin\Education\Admin;
|
||||
|
||||
use WP_List_Table;
|
||||
use WPForms\Admin\Education\EducationInterface;
|
||||
use WPForms\Lite\Integrations\LiteConnect\LiteConnect;
|
||||
use WPForms\Lite\Integrations\LiteConnect\Integration as LiteConnectIntegration;
|
||||
|
||||
/**
|
||||
* Admin/DidYouKnow Education feature.
|
||||
*
|
||||
* @since 1.7.4
|
||||
*/
|
||||
class DidYouKnow implements EducationInterface {
|
||||
|
||||
/**
|
||||
* Indicate if current Education feature is allowed to load.
|
||||
*
|
||||
* @since 1.7.4
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function allow_load() {
|
||||
|
||||
// Load only on the `All Forms` admin page.
|
||||
return wpforms_is_admin_page( 'overview' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Init.
|
||||
*
|
||||
* @since 1.7.4
|
||||
*/
|
||||
public function init() {
|
||||
|
||||
if ( ! $this->allow_load() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Define hooks.
|
||||
$this->hooks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hooks.
|
||||
*
|
||||
* @since 1.7.4
|
||||
*/
|
||||
private function hooks() {
|
||||
|
||||
add_action( 'wpforms_admin_overview_after_rows', [ $this, 'display' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Messages.
|
||||
*
|
||||
* @since 1.7.4
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function messages() {
|
||||
|
||||
return [
|
||||
[
|
||||
'slug' => 'lite-connect',
|
||||
'is_allowed' => LiteConnect::is_allowed(),
|
||||
'cont_class' => LiteConnect::is_enabled() ? 'wpforms-education-lite-connect-setting wpforms-hidden' : 'wpforms-education-lite-connect-setting',
|
||||
'title' => esc_html__( 'Entries are not stored in WPForms Lite', 'wpforms-lite' ),
|
||||
'desc' => esc_html__( 'Entries are available through email notifications. If you enable Entry Backups, you can restore them once you upgrade to WPForms Pro.', 'wpforms-lite' ),
|
||||
'more_title' => esc_html__( 'Enable Entry Backups', 'wpforms-lite' ),
|
||||
'more_link' => admin_url( 'admin.php?page=wpforms-settings' ),
|
||||
'icon' => '<svg fill="#fff" viewBox="0 0 20 14"><path d="M16.78 6.1a3 3 0 0 0-4.47-3.56A4.97 4.97 0 0 0 3 5v.28A4.48 4.48 0 0 0 4.5 14H16a4 4 0 0 0 4-4c0-1.9-1.38-3.53-3.22-3.9Zm-4.37 2-.35.34A.75.75 0 0 1 11 8.4l-1-1.07v3.91c0 .44-.34.75-.75.75h-.5a.72.72 0 0 1-.75-.75v-3.9L6.97 8.4a.75.75 0 0 1-1.06.03l-.35-.35c-.31-.3-.31-.78 0-1.06l2.9-2.9a.74.74 0 0 1 1.04 0l2.9 2.9c.32.28.32.75 0 1.06Z"/></svg>',
|
||||
'item' => 1,
|
||||
'enabled' => [
|
||||
'cont_class' => LiteConnect::is_enabled() ? 'wpforms-education-lite-connect-enabled-info' : 'wpforms-education-lite-connect-enabled-info wpforms-hidden',
|
||||
'title' => esc_html__( 'Entries Backups Are Enabled', 'wpforms-lite' ),
|
||||
'more_title' => esc_html__( 'Restore Form Entries', 'wpforms-lite' ),
|
||||
'more_link' => wpforms_admin_upgrade_link( 'forms-overview', 'restore-entries' ),
|
||||
'more_class' => 'wpforms-is-enabled',
|
||||
'desc' => $this->get_lite_connect_entries_since_info(),
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Random message.
|
||||
*
|
||||
* @since 1.7.4
|
||||
*/
|
||||
private function message_rnd() {
|
||||
|
||||
$messages = $this->messages();
|
||||
|
||||
return $messages[ array_rand( $messages ) ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Display message.
|
||||
*
|
||||
* @since 1.7.4
|
||||
*
|
||||
* @param WP_List_Table $wp_list_table Instance of WP_List_Table.
|
||||
*/
|
||||
public function display( $wp_list_table ) {
|
||||
|
||||
$dismissed = get_user_meta( get_current_user_id(), 'wpforms_dismissed', true );
|
||||
|
||||
// Do not display the message if it was dismissed.
|
||||
if ( ! empty( $dismissed['edu-admin-did-you-know-overview'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$message = $this->message_rnd();
|
||||
|
||||
// Display the message only if it is allowed.
|
||||
if ( isset( $message['is_allowed'] ) && empty( $message['is_allowed'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
echo wpforms_render( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
'education/admin/did-you-know',
|
||||
[
|
||||
'slug' => ! empty( $message['slug'] ) ? $message['slug'] : '',
|
||||
'cols' => $wp_list_table->get_column_count(),
|
||||
'icon' => ! empty( $message['icon'] ) ? $message['icon'] : '',
|
||||
'title' => ! empty( $message['title'] ) ? $message['title'] : esc_html__( 'Did You Know?', 'wpforms-lite' ),
|
||||
'desc' => ! empty( $message['desc'] ) ? $message['desc'] : '',
|
||||
'more_title' => ! empty( $message['more_title'] ) ? $message['more_title'] : esc_html__( 'Learn More', 'wpforms-lite' ),
|
||||
'more_link' => ! empty( $message['more_link'] ) ? $message['more_link'] : '',
|
||||
'more_class' => ! empty( $message['more_class'] ) ? $message['more_class'] : '',
|
||||
'cont_class' => ! empty( $message['cont_class'] ) ? $message['cont_class'] : '',
|
||||
'enabled_title' => ! empty( $message['enabled']['title'] ) ? $message['enabled']['title'] : esc_html__( 'Did You Know?', 'wpforms-lite' ),
|
||||
'enabled_desc' => ! empty( $message['enabled']['desc'] ) ? $message['enabled']['desc'] : '',
|
||||
'enabled_more_title' => ! empty( $message['enabled']['more_title'] ) ? $message['enabled']['more_title'] : esc_html__( 'Learn More', 'wpforms-lite' ),
|
||||
'enabled_more_link' => ! empty( $message['enabled']['more_link'] ) ? $message['enabled']['more_link'] : '',
|
||||
'enabled_more_class' => ! empty( $message['enabled']['more_class'] ) ? $message['enabled']['more_class'] : '',
|
||||
'enabled_cont_class' => ! empty( $message['enabled']['cont_class'] ) ? $message['enabled']['cont_class'] : '',
|
||||
],
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate Lite Connect entries information.
|
||||
*
|
||||
* @since 1.7.4
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_lite_connect_entries_since_info() {
|
||||
|
||||
$entries_count = LiteConnectIntegration::get_new_entries_count();
|
||||
$enabled_since = LiteConnectIntegration::get_enabled_since();
|
||||
|
||||
$string = sprintf(
|
||||
esc_html( /* translators: %d - backed up entries count. */
|
||||
_n(
|
||||
'%d entry backed up',
|
||||
'%d entries backed up',
|
||||
$entries_count,
|
||||
'wpforms-lite'
|
||||
)
|
||||
),
|
||||
absint( $entries_count )
|
||||
);
|
||||
|
||||
if ( ! empty( $enabled_since ) ) {
|
||||
$string .= ' ';
|
||||
$string .= esc_html(
|
||||
sprintf( /* translators: %1$s - time when Lite Connect was enabled. */
|
||||
__( 'since %1$s', 'wpforms-lite' ),
|
||||
wpforms_date_format( $enabled_since, '', true )
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace WPForms\Lite\Admin\Education\Admin;
|
||||
|
||||
use \WPForms\Admin\Education;
|
||||
|
||||
/**
|
||||
* Admin/NoticeBar Education feature for Lite.
|
||||
*
|
||||
* @since 1.6.6
|
||||
*/
|
||||
class NoticeBar implements Education\EducationInterface {
|
||||
|
||||
/**
|
||||
* Indicate if current Education feature is allowed to load.
|
||||
*
|
||||
* @since 1.6.6
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function allow_load() {
|
||||
|
||||
return wpforms_is_admin_page();
|
||||
}
|
||||
|
||||
/**
|
||||
* Init.
|
||||
*
|
||||
* @since 1.6.6
|
||||
*/
|
||||
public function init() {
|
||||
|
||||
if ( ! $this->allow_load() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Define hooks.
|
||||
$this->hooks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hooks.
|
||||
*
|
||||
* @since 1.6.6
|
||||
*/
|
||||
public function hooks() {
|
||||
|
||||
add_action( 'wpforms_admin_header_before', [ $this, 'display' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Notice bar display message.
|
||||
*
|
||||
* @since 1.6.6
|
||||
*/
|
||||
public function display() {
|
||||
|
||||
$dismissed = get_user_meta( get_current_user_id(), 'wpforms_dismissed', true );
|
||||
|
||||
if ( ! empty( $dismissed['edu-admin-notice-bar'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
echo wpforms_render( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
'education/admin/notice-bar',
|
||||
[
|
||||
'upgrade_link' => wpforms_admin_upgrade_link( 'notice-bar', 'Upgrade to WPForms Pro' ),
|
||||
],
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
namespace WPForms\Lite\Admin\Education\Builder;
|
||||
|
||||
use WPForms_Builder_Panel_Settings;
|
||||
use WPForms\Admin\Education\EducationInterface;
|
||||
|
||||
/**
|
||||
* Confirmations Education feature.
|
||||
*
|
||||
* @since 1.6.9
|
||||
*/
|
||||
class Confirmations implements EducationInterface {
|
||||
|
||||
/**
|
||||
* Indicate if current Education feature is allowed to load.
|
||||
*
|
||||
* @since 1.6.9
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function allow_load() {
|
||||
|
||||
return wpforms_is_admin_page( 'builder' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Init.
|
||||
*
|
||||
* @since 1.6.9
|
||||
*/
|
||||
public function init() {
|
||||
|
||||
if ( ! $this->allow_load() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->hooks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load hooks.
|
||||
*
|
||||
* @since 1.6.9
|
||||
*/
|
||||
private function hooks() {
|
||||
|
||||
add_action( 'wpforms_lite_form_settings_confirmations_single_after', [ $this, 'entry_preview_settings' ], 10, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add education settings located in confirmation inside the message block.
|
||||
*
|
||||
* @since 1.6.9
|
||||
*
|
||||
* @param WPForms_Builder_Panel_Settings $settings Builder panel settings.
|
||||
* @param int $field_id Field ID.
|
||||
*/
|
||||
public function entry_preview_settings( $settings, $field_id ) {
|
||||
|
||||
wpforms_panel_field(
|
||||
'toggle',
|
||||
'confirmations',
|
||||
'message_entry_preview',
|
||||
$settings->form_data,
|
||||
esc_html__( 'Show entry preview after confirmation', 'wpforms-lite' ),
|
||||
[
|
||||
'input_id' => 'wpforms-panel-field-confirmations-message_entry_preview-' . wpforms_validate_field_id( $field_id ),
|
||||
'input_class' => 'wpforms-panel-field-confirmations-message_entry_preview education-modal',
|
||||
'parent' => 'settings',
|
||||
'subsection' => wpforms_validate_field_id( $field_id ),
|
||||
'pro_badge' => true,
|
||||
'data' => [
|
||||
'action' => 'upgrade',
|
||||
'name' => esc_html__( 'Show Entry Preview', 'wpforms-lite' ),
|
||||
'utm-content' => 'Show Entry Preview',
|
||||
'licence' => 'pro',
|
||||
],
|
||||
'attrs' => [
|
||||
'disabled' => 'disabled',
|
||||
],
|
||||
'value' => false,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
namespace WPForms\Lite\Admin\Education\Builder;
|
||||
|
||||
use \WPForms\Admin\Education\EducationInterface;
|
||||
|
||||
/**
|
||||
* Builder/DidYouKnow Education feature.
|
||||
*
|
||||
* @since 1.6.6
|
||||
*/
|
||||
class DidYouKnow implements EducationInterface {
|
||||
|
||||
/**
|
||||
* Indicate if current Education feature is allowed to load.
|
||||
*
|
||||
* @since 1.6.6
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function allow_load() {
|
||||
|
||||
return wpforms_is_admin_page( 'builder' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Init.
|
||||
*
|
||||
* @since 1.6.6
|
||||
*/
|
||||
public function init() {
|
||||
|
||||
if ( ! $this->allow_load() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Define hooks.
|
||||
$this->hooks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hooks.
|
||||
*
|
||||
* @since 1.6.6
|
||||
*/
|
||||
public function hooks() {
|
||||
|
||||
add_action( 'wpforms_builder_settings_notifications_after', [ $this, 'notifications' ] );
|
||||
add_action( 'wpforms_builder_settings_confirmations_after', [ $this, 'confirmations' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Display on the Notifications panel.
|
||||
*
|
||||
* @since 1.6.6
|
||||
*/
|
||||
public function notifications() {
|
||||
|
||||
$this->display(
|
||||
'notifications',
|
||||
[ 'desc' => esc_html__( 'You can have multiple notifications with conditional logic.', 'wpforms-lite' ) ]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display on the Confirmations panel.
|
||||
*
|
||||
* @since 1.6.6
|
||||
*/
|
||||
public function confirmations() {
|
||||
|
||||
$this->display(
|
||||
'confirmations',
|
||||
[ 'desc' => esc_html__( 'You can have multiple confirmations with conditional logic.', 'wpforms-lite' ) ]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display message.
|
||||
*
|
||||
* @since 1.6.6
|
||||
*
|
||||
* @param string $section Form builder section/area (slug).
|
||||
* @param array $settings Notice settings array.
|
||||
*/
|
||||
private function display( $section, $settings ) {
|
||||
|
||||
$dismissed = get_user_meta( get_current_user_id(), 'wpforms_dismissed', true );
|
||||
|
||||
// Check if not dismissed.
|
||||
if ( ! empty( $dismissed[ 'edu-builder-did-you-know-' . $section ] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
echo wpforms_render( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
'education/builder/did-you-know',
|
||||
[
|
||||
'desc' => $settings['desc'],
|
||||
'more' => ! empty( $settings['more'] ) ? $settings['more'] : '',
|
||||
'link' => wpforms_admin_upgrade_link( 'Form Builder DYK', ucfirst( $section ) ),
|
||||
'section' => $section,
|
||||
|
||||
],
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,217 @@
|
||||
<?php
|
||||
|
||||
namespace WPForms\Lite\Admin\Education\Builder;
|
||||
|
||||
use WPForms\Admin\Education;
|
||||
use WPForms\Helpers\Form;
|
||||
|
||||
/**
|
||||
* Builder/Fields Education for Lite.
|
||||
*
|
||||
* @since 1.6.6
|
||||
*/
|
||||
class Fields extends Education\Builder\Fields {
|
||||
|
||||
/**
|
||||
* Hooks.
|
||||
*
|
||||
* @since 1.6.6
|
||||
*/
|
||||
public function hooks() {
|
||||
|
||||
add_filter( 'wpforms_builder_fields_buttons', [ $this, 'add_fields' ], 500 );
|
||||
add_filter( 'wpforms_builder_field_button_attributes', [ $this, 'fields_attributes' ], 100, 2 );
|
||||
add_action( 'wpforms_field_options_after_advanced-options', [ $this, 'field_conditional_logic' ] );
|
||||
add_action( 'wpforms_builder_panel_fields_panel_content_title_after', [ $this, 'form_preview_notice' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add fields.
|
||||
*
|
||||
* @since 1.6.6
|
||||
*
|
||||
* @param array|mixed $fields Form fields.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function add_fields( $fields ) {
|
||||
|
||||
$fields = (array) $fields;
|
||||
|
||||
foreach ( $fields as $group => $group_data ) {
|
||||
$edu_fields = $this->fields->get_by_group( $group );
|
||||
$edu_fields = $this->fields->set_values( $edu_fields, 'class', 'education-modal', 'empty' );
|
||||
|
||||
foreach ( $edu_fields as $edu_field ) {
|
||||
|
||||
// Skip if in the current group already exist field of this type.
|
||||
if ( ! empty( wp_list_filter( $group_data, [ 'type' => $edu_field['type'] ] ) ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$addon = ! empty( $edu_field['addon'] ) ? $this->addons->get_addon( $edu_field['addon'] ) : [];
|
||||
|
||||
if ( ! empty( $addon ) ) {
|
||||
$edu_field['license'] = $addon['license_level'] ?? '';
|
||||
}
|
||||
|
||||
$fields[ $group ]['fields'][] = $edu_field;
|
||||
}
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a conditional logic settings section for fields inside the form builder.
|
||||
*
|
||||
* @since 1.6.6
|
||||
*
|
||||
* @param array $field Field data.
|
||||
*/
|
||||
public function field_conditional_logic( array $field ): void {
|
||||
|
||||
// Certain fields don't support conditional logic.
|
||||
if ( in_array( $field['type'], [ 'pagebreak', 'divider', 'hidden' ], true ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
?>
|
||||
<div class="wpforms-field-option-group wpforms-field-option-group-conditionals">
|
||||
<a href="#"
|
||||
class="wpforms-field-option-group-toggle education-modal"
|
||||
data-name="<?php esc_attr_e( 'Smart Conditional Logic', 'wpforms-lite' ); ?>"
|
||||
data-utm-content="Smart Conditional Logic">
|
||||
<?php esc_html_e( 'Smart Logic', 'wpforms-lite' ); ?>
|
||||
</a>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust attributes on field buttons.
|
||||
*
|
||||
* @since 1.6.6
|
||||
*
|
||||
* @param array|mixed $atts Button attributes.
|
||||
* @param array $field Button properties.
|
||||
*
|
||||
* @return array Attributes array.
|
||||
*/
|
||||
public function fields_attributes( $atts, $field ) {
|
||||
|
||||
$atts = (array) $atts;
|
||||
|
||||
$atts['data']['utm-content'] = ! empty( $field['name_en'] ) ? $field['name_en'] : '';
|
||||
|
||||
if ( ! empty( $field['class'] ) && $field['class'] === 'education-modal' ) {
|
||||
$atts['class'][] = 'wpforms-not-available';
|
||||
}
|
||||
|
||||
if ( empty( $field['addon'] ) ) {
|
||||
return $atts;
|
||||
}
|
||||
|
||||
$addon = $this->addons->get_addon( $field['addon'] );
|
||||
|
||||
if ( empty( $addon ) ) {
|
||||
return $atts;
|
||||
}
|
||||
|
||||
if ( ! empty( $addon['video'] ) ) {
|
||||
$atts['data']['video'] = $addon['video'];
|
||||
}
|
||||
|
||||
if ( ! empty( $field['license'] ) ) {
|
||||
$atts['data']['license'] = $field['license'];
|
||||
}
|
||||
|
||||
return $atts;
|
||||
}
|
||||
|
||||
/**
|
||||
* The form preview Pro fields notice.
|
||||
*
|
||||
* @since 1.9.4
|
||||
*
|
||||
* @param array $form_data Form data.
|
||||
*
|
||||
* @noinspection HtmlUnknownTarget
|
||||
*/
|
||||
public function form_preview_notice( array $form_data ): void {
|
||||
|
||||
$dismissed = get_user_meta( get_current_user_id(), 'wpforms_dismissed', true );
|
||||
$pro_fields = Form::get_form_pro_fields( $form_data );
|
||||
$is_quiz_enabled = ! empty( $form_data['settings']['quiz']['enabled'] );
|
||||
|
||||
// Check whether the notice is dismissed OR the form doesn't contain Pro fields.
|
||||
if (
|
||||
! empty( $dismissed['edu-pro-fields-form-preview-notice'] ) ||
|
||||
( empty( $pro_fields ) && ! $is_quiz_enabled )
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( $is_quiz_enabled ) {
|
||||
$this->print_quiz_notice();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$content = sprintf(
|
||||
wp_kses( /* translators: %s - WPForms.com announcement page URL. */
|
||||
__( 'They will not be present in the published form. <a href="%1$s" target="_blank" rel="noopener noreferrer">Upgrade now</a> to unlock these features.', 'wpforms-lite' ),
|
||||
[
|
||||
'a' => [
|
||||
'href' => [],
|
||||
'target' => [],
|
||||
'rel' => [],
|
||||
],
|
||||
]
|
||||
),
|
||||
wpforms_admin_upgrade_link( 'Builder - Settings', 'AI Form - Pro Fields in Lite notice' )
|
||||
);
|
||||
|
||||
$this->print_form_preview_notice(
|
||||
[
|
||||
'class' => 'wpforms-alert-warning',
|
||||
'title' => esc_html__( 'Your Form Contains Pro Fields', 'wpforms-lite' ),
|
||||
'content' => $content,
|
||||
'dismiss_section' => 'pro-fields-form-preview-notice',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the Quiz addon notice.
|
||||
*
|
||||
* @since 1.9.9
|
||||
*
|
||||
* @noinspection HtmlUnknownTarget
|
||||
*/
|
||||
private function print_quiz_notice(): void {
|
||||
|
||||
$content = sprintf(
|
||||
wp_kses( /* translators: %s - Upgrade license page URL. */
|
||||
__( 'Quiz functionality will not be present in the published form. <a href="%1$s" target="_blank" rel="noopener noreferrer">Upgrade now</a> to unlock the Quiz Addon.', 'wpforms-lite' ),
|
||||
[
|
||||
'a' => [
|
||||
'href' => [],
|
||||
'target' => [],
|
||||
'rel' => [],
|
||||
],
|
||||
]
|
||||
),
|
||||
wpforms_admin_upgrade_link( 'Builder - Settings', 'AI Form - Quiz addon in Lite notice' )
|
||||
);
|
||||
|
||||
$this->print_form_preview_notice(
|
||||
[
|
||||
'class' => 'wpforms-alert-warning',
|
||||
'title' => esc_html__( 'Your Form Uses the Quiz Addon', 'wpforms-lite' ),
|
||||
'content' => $content,
|
||||
'dismiss_section' => 'quiz-form-preview-notice',
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
<?php
|
||||
|
||||
namespace WPForms\Lite\Admin\Education\Builder;
|
||||
|
||||
use WPForms\Admin\Education\EducationInterface;
|
||||
use WPForms_Builder_Panel_Settings;
|
||||
|
||||
/**
|
||||
* Notifications Education feature.
|
||||
*
|
||||
* @since 1.7.7
|
||||
*/
|
||||
class Notifications implements EducationInterface {
|
||||
|
||||
/**
|
||||
* Init.
|
||||
*
|
||||
* @since 1.7.7
|
||||
*/
|
||||
public function init() {
|
||||
|
||||
if ( ! $this->allow_load() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->hooks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate if current Education feature is allowed to load.
|
||||
*
|
||||
* @since 1.7.7
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function allow_load() {
|
||||
|
||||
return wpforms_is_admin_page( 'builder' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Load hooks.
|
||||
*
|
||||
* @since 1.7.7
|
||||
*/
|
||||
private function hooks() {
|
||||
|
||||
add_action( 'wpforms_lite_form_settings_notifications_block_content_after', [ $this, 'advanced_section' ], 10, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Output Notification Advanced section.
|
||||
*
|
||||
* @since 1.7.7
|
||||
*
|
||||
* @param WPForms_Builder_Panel_Settings $settings Builder panel settings.
|
||||
* @param int $id Notification id.
|
||||
*/
|
||||
public function advanced_section( $settings, $id ) {
|
||||
|
||||
/**
|
||||
* Filter the "Advanced" content.
|
||||
*
|
||||
* @since 1.8.5
|
||||
*
|
||||
* @param string $content The content.
|
||||
* @param WPForms_Builder_Panel_Settings $settings Builder panel settings.
|
||||
* @param int $id Notification id.
|
||||
*/
|
||||
$content = apply_filters( 'wpforms_lite_admin_education_builder_notifications_advanced_settings_content', '', $settings, $id );
|
||||
|
||||
$content .= wpforms_panel_field(
|
||||
'toggle',
|
||||
'notifications',
|
||||
'file_upload_attachment_enable',
|
||||
$settings->form_data,
|
||||
esc_html__( 'Enable File Upload Attachments', 'wpforms-lite' ),
|
||||
[
|
||||
'input_class' => 'notifications_enable_file_upload_attachment_toggle education-modal',
|
||||
'parent' => 'settings',
|
||||
'subsection' => $id,
|
||||
'pro_badge' => true,
|
||||
'data' => [
|
||||
'action' => 'upgrade',
|
||||
'name' => esc_html__( 'File Upload Attachments', 'wpforms-lite' ),
|
||||
'utm-content' => 'File Upload Attachments',
|
||||
'licence' => 'pro',
|
||||
],
|
||||
'attrs' => [
|
||||
'disabled' => 'disabled',
|
||||
],
|
||||
'value' => false,
|
||||
],
|
||||
false
|
||||
);
|
||||
|
||||
$content .= wpforms_panel_field(
|
||||
'toggle',
|
||||
'notifications',
|
||||
'entry_csv_attachment_enable',
|
||||
$settings->form_data,
|
||||
esc_html__( 'Enable Entry CSV Attachment', 'wpforms-lite' ),
|
||||
[
|
||||
'input_class' => 'notifications_enable_entry_csv_attachment_toggle education-modal',
|
||||
'parent' => 'settings',
|
||||
'subsection' => $id,
|
||||
'pro_badge' => true,
|
||||
'data' => [
|
||||
'action' => 'upgrade',
|
||||
'name' => esc_html__( 'Entry CSV Attachment', 'wpforms-lite' ),
|
||||
'utm-content' => 'Entry CSV Attachment',
|
||||
'licence' => 'pro',
|
||||
],
|
||||
'attrs' => [
|
||||
'disabled' => 'disabled',
|
||||
],
|
||||
'value' => false,
|
||||
],
|
||||
false
|
||||
);
|
||||
|
||||
// Wrap advanced settings to the unfoldable group.
|
||||
wpforms_panel_fields_group(
|
||||
$content,
|
||||
[
|
||||
'borders' => [ 'top' ],
|
||||
'class' => 'wpforms-builder-notifications-advanced opened',
|
||||
'default' => 'opened',
|
||||
'group' => 'settings_notifications_advanced',
|
||||
'title' => esc_html__( 'Advanced', 'wpforms-lite' ),
|
||||
'unfoldable' => true,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace WPForms\Lite\Admin\Education;
|
||||
|
||||
/**
|
||||
* Education core for Lite.
|
||||
*
|
||||
* @since 1.6.6
|
||||
*/
|
||||
class Core extends \WPForms\Admin\Education\Core {
|
||||
|
||||
/**
|
||||
* Hooks.
|
||||
*
|
||||
* @since 1.6.6
|
||||
*/
|
||||
protected function hooks() {
|
||||
|
||||
parent::hooks();
|
||||
|
||||
add_action( 'admin_enqueue_scripts', [ $this, 'enqueues' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Load enqueues.
|
||||
*
|
||||
* @since 1.6.6
|
||||
*/
|
||||
public function enqueues() {
|
||||
|
||||
parent::enqueues();
|
||||
|
||||
$min = wpforms_get_min_suffix();
|
||||
|
||||
wp_enqueue_script(
|
||||
'wpforms-lite-admin-education-core',
|
||||
WPFORMS_PLUGIN_URL . "assets/lite/js/admin/education/core{$min}.js",
|
||||
[ 'wpforms-admin-education-core' ],
|
||||
WPFORMS_VERSION,
|
||||
false
|
||||
);
|
||||
|
||||
// Builder Education styles.
|
||||
if ( wpforms_is_admin_page( 'builder' ) ) {
|
||||
wp_enqueue_style(
|
||||
'wpforms-lite-admin-education-builder',
|
||||
WPFORMS_PLUGIN_URL . "assets/lite/css/builder-education{$min}.css",
|
||||
[],
|
||||
WPFORMS_VERSION
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,469 @@
|
||||
<?php
|
||||
|
||||
namespace WPForms\Lite\Admin\Education;
|
||||
|
||||
use WPForms\Admin\Education;
|
||||
use WPForms\Integrations\LiteConnect\API;
|
||||
use WPForms\Lite\Integrations\LiteConnect\LiteConnect as LiteConnectClass;
|
||||
use WPForms\Lite\Integrations\LiteConnect\Integration as LiteConnectIntegration;
|
||||
|
||||
/**
|
||||
* Admin/Settings/LiteConnect Education feature for Lite.
|
||||
*
|
||||
* @since 1.7.4
|
||||
*/
|
||||
class LiteConnect implements Education\EducationInterface {
|
||||
|
||||
/**
|
||||
* Indicate if Lite Connect entry backup is enabled.
|
||||
*
|
||||
* @since 1.7.4
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $is_enabled;
|
||||
|
||||
/**
|
||||
* Indicate if current Education feature is allowed to load.
|
||||
*
|
||||
* @since 1.7.4
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function allow_load() {
|
||||
|
||||
// Do not load if Lite Connect integration is not allowed.
|
||||
if ( ! LiteConnectClass::is_allowed() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Do not load if user doesn't have permissions to update settings.
|
||||
if ( ! wpforms_current_user_can( wpforms_get_capability_manage_options() ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Load only in certain cases.
|
||||
return wp_doing_ajax() ||
|
||||
wpforms_is_admin_page( 'builder' ) ||
|
||||
wpforms_is_admin_page( 'settings' ) ||
|
||||
wpforms_is_admin_page( 'overview' ) ||
|
||||
wpforms_is_admin_page( 'entries' ) ||
|
||||
$this->is_dashboard() ||
|
||||
$this->is_embed_page();
|
||||
}
|
||||
|
||||
/**
|
||||
* Init.
|
||||
*
|
||||
* @since 1.7.4
|
||||
*/
|
||||
public function init() {
|
||||
|
||||
if ( ! $this->allow_load() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->is_enabled = LiteConnectClass::is_enabled() ? 1 : 0;
|
||||
|
||||
// Define hooks.
|
||||
$this->hooks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hooks.
|
||||
*
|
||||
* @since 1.7.4
|
||||
*/
|
||||
private function hooks() {
|
||||
|
||||
add_action( 'admin_footer', [ $this, 'modal_template' ], 10, 2 );
|
||||
add_action( 'admin_enqueue_scripts', [ $this, 'enqueues' ] );
|
||||
|
||||
// Ajax action.
|
||||
add_action( 'wp_ajax_wpforms_update_lite_connect_enabled_setting', [ $this, 'ajax_update_lite_connect_enabled_setting' ] );
|
||||
add_action( 'wp_ajax_wpforms_lite_connect_finalize', [ $this, 'ajax_lite_connect_finalize' ] );
|
||||
|
||||
// Content filters.
|
||||
add_filter( 'wpforms_lite_admin_dashboard_widget_content_html_chart_block_before', [ $this, 'dashboard_widget_before_content' ] );
|
||||
add_filter( 'wpforms_builder_output_before_toolbar', [ $this, 'top_bar_content' ] );
|
||||
add_filter( 'wpforms_admin_challenge_embed_template_congrats_popup_footer', [ $this, 'challenge_popup_footer_content' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether it is the Dashboard admin page.
|
||||
*
|
||||
* @since 1.7.4
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_dashboard() {
|
||||
|
||||
global $pagenow;
|
||||
|
||||
return $pagenow === 'index.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether it is the form embedding admin page (Edit Post or Edit Page).
|
||||
*
|
||||
* @since 1.7.4
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_embed_page() {
|
||||
|
||||
if ( function_exists( 'get_current_screen' ) ) {
|
||||
return wpforms()->obj( 'challenge' )->is_form_embed_page();
|
||||
}
|
||||
|
||||
global $pagenow;
|
||||
|
||||
return in_array( $pagenow, [ 'edit.php', 'post.php', 'post-new.php' ], true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Load enqueues.
|
||||
*
|
||||
* @since 1.7.4
|
||||
*/
|
||||
public function enqueues() {
|
||||
|
||||
$min = wpforms_get_min_suffix();
|
||||
|
||||
// On the Dashboard and form embedding pages we should load additional scripts and styles.
|
||||
if ( $this->is_dashboard() || $this->is_embed_page() ) {
|
||||
$this->dashboard_enqueues();
|
||||
}
|
||||
|
||||
wp_enqueue_script(
|
||||
'wpforms-lite-admin-education-lite-connect',
|
||||
WPFORMS_PLUGIN_URL . "assets/lite/js/admin/education/lite-connect{$min}.js",
|
||||
[ 'jquery', 'wp-util' ],
|
||||
WPFORMS_VERSION,
|
||||
true
|
||||
);
|
||||
|
||||
wp_localize_script(
|
||||
'wpforms-lite-admin-education-lite-connect',
|
||||
'wpforms_education_lite_connect',
|
||||
$this->get_js_strings()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dashboard enqueues.
|
||||
*
|
||||
* @since 1.7.4
|
||||
*/
|
||||
private function dashboard_enqueues() {
|
||||
|
||||
$min = wpforms_get_min_suffix();
|
||||
|
||||
// jQuery.Confirm Reloaded.
|
||||
wp_enqueue_script(
|
||||
'jquery-confirm',
|
||||
WPFORMS_PLUGIN_URL . 'assets/lib/jquery.confirm/jquery-confirm.min.js',
|
||||
[ 'jquery' ],
|
||||
'1.0.0',
|
||||
true
|
||||
);
|
||||
|
||||
// jQuery.Confirm Reloaded.
|
||||
wp_enqueue_style(
|
||||
'jquery-confirm',
|
||||
WPFORMS_PLUGIN_URL . 'assets/lib/jquery.confirm/jquery-confirm.min.css',
|
||||
[],
|
||||
'1.0.0'
|
||||
);
|
||||
|
||||
// FontAwesome.
|
||||
wp_enqueue_style(
|
||||
'wpforms-font-awesome',
|
||||
WPFORMS_PLUGIN_URL . 'assets/lib/font-awesome/css/all.min.css',
|
||||
null,
|
||||
'7.0.1'
|
||||
);
|
||||
|
||||
// FontAwesome v4 compatibility shims.
|
||||
wp_enqueue_style(
|
||||
'wpforms-font-awesome-v4-shim',
|
||||
WPFORMS_PLUGIN_URL . 'assets/lib/font-awesome/css/v4-shims.min.css',
|
||||
null,
|
||||
'4.7.0'
|
||||
);
|
||||
|
||||
// Dashboard Education styles.
|
||||
wp_enqueue_style(
|
||||
'wpforms-lite-admin-education-lite-connect',
|
||||
WPFORMS_PLUGIN_URL . "assets/lite/css/dashboard-education{$min}.css",
|
||||
[],
|
||||
WPFORMS_VERSION
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirmation modal template.
|
||||
*
|
||||
* @since 1.7.4
|
||||
*/
|
||||
public function modal_template() {
|
||||
|
||||
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
echo wpforms_render( 'education/lite-connect-modal' );
|
||||
|
||||
if ( wpforms_is_admin_page( 'builder' ) ) {
|
||||
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
echo wpforms_render( 'education/builder/lite-connect/ai-modal' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get localize strings.
|
||||
*
|
||||
* @since 1.7.4
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_js_strings() {
|
||||
|
||||
return [
|
||||
'ajax_url' => admin_url( 'admin-ajax.php' ),
|
||||
'nonce' => wp_create_nonce( 'wpforms-lite-connect-toggle' ),
|
||||
'is_enabled' => $this->is_enabled,
|
||||
'enable_modal' => [
|
||||
'confirm' => esc_html__( 'Enable Entry Backups', 'wpforms-lite' ),
|
||||
'cancel' => esc_html__( 'No Thanks', 'wpforms-lite' ),
|
||||
],
|
||||
'enable_ai' => [
|
||||
'confirm' => esc_html__( 'Enable AI Features', 'wpforms-lite' ),
|
||||
'enabled_title' => esc_html__( 'AI Features Enabled', 'wpforms-lite' ),
|
||||
],
|
||||
'disable_modal' => [
|
||||
'title' => esc_html__( 'Are you sure?', 'wpforms-lite' ),
|
||||
'content' => esc_html__( 'If you disable Lite Connect, you will no longer be able to restore your entries when you upgrade to WPForms Pro.', 'wpforms-lite' ),
|
||||
'confirm' => esc_html__( 'Disable Entry Backups', 'wpforms-lite' ),
|
||||
'cancel' => esc_html__( 'Cancel', 'wpforms-lite' ),
|
||||
],
|
||||
'update_result' => [
|
||||
'enabled_title' => esc_html__( 'Entry Backups Enabled', 'wpforms-lite' ),
|
||||
'enabled' => esc_html__( 'Awesome! If you decide to upgrade to WPForms Pro, you can restore your entries and will have instant access to reports.', 'wpforms-lite' ),
|
||||
'disabled_title' => esc_html__( 'Entry Backups Disabled', 'wpforms-lite' ),
|
||||
'disabled' => esc_html__( 'Form Entry Backups were successfully disabled.', 'wpforms-lite' ),
|
||||
'error_title' => esc_html__( 'Error', 'wpforms-lite' ),
|
||||
'error' => esc_html__( 'Unfortunately, the error occurs while updating Form Entry Backups setting. Please try again later.', 'wpforms-lite' ),
|
||||
'close' => esc_html__( 'Close', 'wpforms-lite' ),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate Lite Connect entries information.
|
||||
*
|
||||
* @since 1.7.4
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_lite_connect_entries_since_info() {
|
||||
|
||||
$entries_count = LiteConnectIntegration::get_new_entries_count();
|
||||
$enabled_since = LiteConnectIntegration::get_enabled_since();
|
||||
|
||||
$string = sprintf(
|
||||
esc_html( /* translators: %d - backed up entries count. */
|
||||
_n(
|
||||
'%d entry backed up',
|
||||
'%d entries backed up',
|
||||
$entries_count,
|
||||
'wpforms-lite'
|
||||
)
|
||||
),
|
||||
absint( $entries_count )
|
||||
);
|
||||
|
||||
if ( ! empty( $enabled_since ) ) {
|
||||
$string .= ' ' . sprintf(
|
||||
/* translators: %s - time when Lite Connect was enabled. */
|
||||
esc_html__( 'since %s', 'wpforms-lite' ),
|
||||
esc_html( wpforms_date_format( $enabled_since, '', true ) )
|
||||
);
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add content before the Chart block in the Dashboard Widget.
|
||||
*
|
||||
* @since 1.7.4
|
||||
*
|
||||
* @param string $content Content.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function dashboard_widget_before_content( $content ) {
|
||||
|
||||
$toggle = wpforms_panel_field_toggle_control(
|
||||
[
|
||||
'control-class' => 'wpforms-setting-lite-connect-auto-save-toggle',
|
||||
],
|
||||
'wpforms-setting-lite-connect-enabled',
|
||||
'',
|
||||
esc_html__( 'Enable Form Entry Backups', 'wpforms-lite' ),
|
||||
$this->is_enabled,
|
||||
'disabled'
|
||||
);
|
||||
|
||||
return wpforms_render(
|
||||
'education/admin/lite-connect/dashboard-widget-before',
|
||||
[
|
||||
'toggle' => $toggle,
|
||||
'is_enabled' => $this->is_enabled,
|
||||
'entries_since_info' => $this->get_lite_connect_entries_since_info(),
|
||||
],
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add top bar before the toolbar in the Form Builder.
|
||||
*
|
||||
* @since 1.7.4
|
||||
*
|
||||
* @param string $content Content before the toolbar. Defaults to empty string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function top_bar_content( $content ) {
|
||||
|
||||
if ( $this->is_enabled ) {
|
||||
return $content;
|
||||
}
|
||||
|
||||
$dismissed = get_user_meta( get_current_user_id(), 'wpforms_dismissed', true );
|
||||
|
||||
// Skip when top bar is dismissed.
|
||||
if ( ! empty( $dismissed['edu-builder-lite-connect-top-bar'] ) ) {
|
||||
return $content;
|
||||
}
|
||||
|
||||
$toggle = wpforms_panel_field_toggle_control(
|
||||
[
|
||||
'control-class' => 'wpforms-setting-lite-connect-auto-save-toggle',
|
||||
],
|
||||
'wpforms-setting-lite-connect-enabled',
|
||||
'',
|
||||
esc_html__( 'Enable Form Entry Backups for Free', 'wpforms-lite' ),
|
||||
$this->is_enabled,
|
||||
'disabled'
|
||||
);
|
||||
|
||||
return wpforms_render(
|
||||
'education/builder/lite-connect/top-bar',
|
||||
[
|
||||
'toggle' => $toggle,
|
||||
'is_enabled' => $this->is_enabled,
|
||||
],
|
||||
true
|
||||
) . $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Challenge Congrats popup footer.
|
||||
*
|
||||
* @since 1.7.4
|
||||
*
|
||||
* @param string $content Footer content.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function challenge_popup_footer_content( $content ) {
|
||||
|
||||
if ( $this->is_enabled ) {
|
||||
return $content;
|
||||
}
|
||||
|
||||
$toggle = wpforms_panel_field_toggle_control(
|
||||
[
|
||||
'control-class' => 'wpforms-setting-lite-connect-auto-save-toggle',
|
||||
],
|
||||
'wpforms-setting-lite-connect-enabled',
|
||||
'',
|
||||
esc_html__( 'Enable Form Entry Backups for Free', 'wpforms-lite' ),
|
||||
$this->is_enabled,
|
||||
'disabled'
|
||||
);
|
||||
|
||||
return wpforms_render(
|
||||
'education/admin/lite-connect/challenge-popup-footer',
|
||||
[
|
||||
'toggle' => $toggle,
|
||||
'is_enabled' => $this->is_enabled,
|
||||
],
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX checks.
|
||||
*
|
||||
* @since 1.9.1
|
||||
*/
|
||||
private function ajax_checks() {
|
||||
|
||||
// Run a security check.
|
||||
check_ajax_referer( 'wpforms-lite-connect-toggle', 'nonce' );
|
||||
|
||||
// Check for permissions.
|
||||
if ( ! wpforms_current_user_can( wpforms_get_capability_manage_options() ) ) {
|
||||
wp_send_json_error( esc_html__( 'You do not have permission.', 'wpforms-lite' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX action: update Lite Connect Enabled setting.
|
||||
*
|
||||
* @since 1.7.4
|
||||
*/
|
||||
public function ajax_update_lite_connect_enabled_setting() {
|
||||
|
||||
$this->ajax_checks();
|
||||
|
||||
$slug = LiteConnectClass::SETTINGS_SLUG;
|
||||
|
||||
$settings = get_option( 'wpforms_settings', [] );
|
||||
$settings[ $slug ] = ! empty( $_POST['value'] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||||
|
||||
wpforms_update_settings( $settings );
|
||||
|
||||
if ( ! $settings[ $slug ] ) {
|
||||
wp_send_json_success( '' );
|
||||
}
|
||||
|
||||
// Reset generate key attempts counter.
|
||||
update_option( API::GENERATE_KEY_ATTEMPT_COUNTER_OPTION, 0 );
|
||||
|
||||
// We have to start requesting site keys in ajax, turning on the LC functionality.
|
||||
// First, the request to the API server will be sent.
|
||||
// Second, the server will respond to our callback URL /wpforms/auth/key/nonce, and the site key will be stored in the DB.
|
||||
// Third, we have to get access via a separate HTTP request.
|
||||
( new LiteConnectIntegration() )->update_keys(); // First request here.
|
||||
|
||||
wp_send_json_success( $this->get_lite_connect_entries_since_info() );
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX action: Finalize Lite Connect setup.
|
||||
*
|
||||
* @since 1.9.1
|
||||
*/
|
||||
public function ajax_lite_connect_finalize() {
|
||||
|
||||
$this->ajax_checks();
|
||||
|
||||
if ( $this->is_enabled ) {
|
||||
( new LiteConnectIntegration() )->update_keys(); // Simulate third request.
|
||||
}
|
||||
|
||||
wp_send_json_success();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
|
||||
namespace WPForms\Lite\Admin\Pages;
|
||||
|
||||
/**
|
||||
* Addons page for Lite.
|
||||
*
|
||||
* @since 1.6.7
|
||||
*/
|
||||
class Addons {
|
||||
|
||||
/**
|
||||
* Page slug.
|
||||
*
|
||||
* @since 1.6.7
|
||||
*
|
||||
* @type string
|
||||
*/
|
||||
const SLUG = 'addons';
|
||||
|
||||
/**
|
||||
* Determine if current class is allowed to load.
|
||||
*
|
||||
* @since 1.6.7
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function allow_load() {
|
||||
|
||||
return wpforms_is_admin_page( self::SLUG );
|
||||
}
|
||||
|
||||
/**
|
||||
* Init.
|
||||
*
|
||||
* @since 1.6.7
|
||||
*/
|
||||
public function init() {
|
||||
|
||||
if ( ! $this->allow_load() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Define hooks.
|
||||
$this->hooks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hooks.
|
||||
*
|
||||
* @since 1.6.7
|
||||
*/
|
||||
public function hooks() {
|
||||
|
||||
add_action( 'admin_enqueue_scripts', [ $this, 'enqueues' ] );
|
||||
add_action( 'admin_notices', [ $this, 'notices' ] );
|
||||
add_action( 'wpforms_admin_page', [ $this, 'output' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add appropriate scripts to the Addons page.
|
||||
*
|
||||
* @since 1.6.7
|
||||
*/
|
||||
public function enqueues() {
|
||||
|
||||
// JavaScript.
|
||||
wp_enqueue_script(
|
||||
'listjs',
|
||||
WPFORMS_PLUGIN_URL . 'assets/lib/list.min.js',
|
||||
[ 'jquery' ],
|
||||
'1.5.0',
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notices.
|
||||
*
|
||||
* @since 1.6.7.1
|
||||
*/
|
||||
public function notices() {
|
||||
|
||||
$notice = sprintf(
|
||||
'<p class="notice-title"><strong>%1$s</strong></p>
|
||||
<p>%2$s</p>
|
||||
<p class="notice-buttons">
|
||||
<a href="%3$s" class="wpforms-btn wpforms-btn-orange wpforms-btn-md" target="_blank" rel="noopener noreferrer">
|
||||
%4$s
|
||||
</a>
|
||||
</p>',
|
||||
esc_html__( 'Upgrade to Unlock WPForms Addons', 'wpforms-lite' ),
|
||||
esc_html__( 'Access powerful marketing and payment integrations, advanced form fields, and more when you purchase our Plus, Pro, or Elite plans.', 'wpforms-lite' ),
|
||||
esc_url( wpforms_admin_upgrade_link( 'addons', 'All Addons' ) ),
|
||||
esc_html__( 'Upgrade Now', 'wpforms-lite' )
|
||||
);
|
||||
|
||||
\WPForms\Admin\Notice::info(
|
||||
$notice,
|
||||
[ 'autop' => false ]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the Addons page.
|
||||
*
|
||||
* @since 1.6.7
|
||||
*/
|
||||
public function output() {
|
||||
|
||||
$addons = wpforms()->obj( 'addons' )->get_all();
|
||||
|
||||
if ( empty( $addons ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// WPForms 1.8.7 core includes Custom Captcha.
|
||||
// The Custom Captcha addon will only work on WPForms 1.8.6 and earlier versions.
|
||||
unset( $addons['wpforms-captcha'] );
|
||||
|
||||
echo wpforms_render( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
'admin/addons',
|
||||
[
|
||||
'upgrade_link_base' => wpforms_admin_upgrade_link( 'addons' ),
|
||||
'addons' => $addons,
|
||||
],
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
<?php
|
||||
|
||||
namespace WPForms\Lite\Admin\Settings;
|
||||
|
||||
use WPForms\Admin\Education\Helpers;
|
||||
|
||||
/**
|
||||
* Settings Access tab.
|
||||
*
|
||||
* @since 1.5.8
|
||||
*/
|
||||
class Access {
|
||||
|
||||
/**
|
||||
* View slug.
|
||||
*
|
||||
* @since 1.5.8
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const SLUG = 'access';
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @since 1.5.8
|
||||
*/
|
||||
public function __construct() {
|
||||
|
||||
$this->hooks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hooks.
|
||||
*
|
||||
* @since 1.5.8
|
||||
*/
|
||||
public function hooks() {
|
||||
|
||||
add_action( 'admin_enqueue_scripts', [ $this, 'enqueues' ] );
|
||||
add_filter( 'wpforms_settings_tabs', [ $this, 'add_tab' ] );
|
||||
add_filter( 'wpforms_settings_defaults', [ $this, 'add_section' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueues.
|
||||
*
|
||||
* @since 1.5.8
|
||||
*/
|
||||
public function enqueues() {
|
||||
|
||||
if ( ! wpforms_is_admin_page( 'settings', self::SLUG ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Lity.
|
||||
wp_enqueue_style(
|
||||
'wpforms-lity',
|
||||
WPFORMS_PLUGIN_URL . 'assets/lib/lity/lity.min.css',
|
||||
null,
|
||||
'3.0.0'
|
||||
);
|
||||
|
||||
wp_enqueue_script(
|
||||
'wpforms-lity',
|
||||
WPFORMS_PLUGIN_URL . 'assets/lib/lity/lity.min.js',
|
||||
[ 'jquery' ],
|
||||
'3.0.0',
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Access tab.
|
||||
*
|
||||
* @since 1.5.8
|
||||
*
|
||||
* @param array $tabs Array of tabs.
|
||||
*
|
||||
* @return array Array of tabs.
|
||||
*/
|
||||
public function add_tab( $tabs ) {
|
||||
|
||||
$tab = [
|
||||
self::SLUG => [
|
||||
'name' => esc_html__( 'Access', 'wpforms-lite' ),
|
||||
'form' => false,
|
||||
'submit' => false,
|
||||
],
|
||||
];
|
||||
|
||||
return wpforms_list_insert_after( $tabs, 'geolocation', $tab );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Access settings section.
|
||||
*
|
||||
* @since 1.5.8
|
||||
*
|
||||
* @param array $settings Settings sections.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function add_section( $settings ) {
|
||||
|
||||
$settings[ self::SLUG ][ self::SLUG . '-page' ] = [
|
||||
'id' => self::SLUG . '-page',
|
||||
'content' => wpforms_render( 'education/admin/page', $this->template_data(),true ),
|
||||
'type' => 'content',
|
||||
'no_label' => true,
|
||||
];
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the template data.
|
||||
*
|
||||
* @since 1.8.6
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function template_data(): array {
|
||||
|
||||
$images_url = WPFORMS_PLUGIN_URL . 'assets/images/lite-settings-access/';
|
||||
|
||||
return [
|
||||
'features' => [
|
||||
__( 'Create Forms', 'wpforms-lite' ),
|
||||
__( 'Delete Forms', 'wpforms-lite' ),
|
||||
__( 'Edit Forms Entries', 'wpforms-lite' ),
|
||||
__( 'Edit Forms', 'wpforms-lite' ),
|
||||
__( 'Delete Others Forms', 'wpforms-lite' ),
|
||||
__( 'Edit Others Forms Entries', 'wpforms-lite' ),
|
||||
__( 'Edit Others Forms', 'wpforms-lite' ),
|
||||
__( 'View Forms Entries', 'wpforms-lite' ),
|
||||
__( 'Delete Forms Entries', 'wpforms-lite' ),
|
||||
__( 'View Forms', 'wpforms-lite' ),
|
||||
__( 'View Others Forms Entries', 'wpforms-lite' ),
|
||||
__( 'Delete Others Forms Entries', 'wpforms-lite' ),
|
||||
__( 'View Others Forms', 'wpforms-lite' ),
|
||||
],
|
||||
'images' => [
|
||||
[
|
||||
'url' => $images_url . 'screenshot-access-controls.png',
|
||||
'url2x' => $images_url . 'screenshot-access-controls@2x.png',
|
||||
'title' => __( 'Simple Built-in Controls', 'wpforms-lite' ),
|
||||
],
|
||||
[
|
||||
'url' => $images_url . 'screenshot-members.png',
|
||||
'url2x' => $images_url . 'screenshot-members@2x.png',
|
||||
'title' => __( 'Members Integration', 'wpforms-lite' ),
|
||||
],
|
||||
[
|
||||
'url' => $images_url . 'screenshot-user-role-editor.png',
|
||||
'url2x' => $images_url . 'screenshot-user-role-editor@2x.png',
|
||||
'title' => __( 'User Role Editor Integration', 'wpforms-lite' ),
|
||||
],
|
||||
],
|
||||
'utm_medium' => 'Settings - Access',
|
||||
'utm_content' => 'Access Controls',
|
||||
'heading_title' => __( 'Access Controls', 'wpforms-lite' ),
|
||||
'heading_description' => sprintf(
|
||||
'<p>%1$s</p>',
|
||||
__( 'Access controls allows you to manage and customize access to WPForms functionality. You can easily grant or restrict access using the simple built-in controls, or use our official integrations with Members and User Role Editor plugins.', 'wpforms-lite' )
|
||||
),
|
||||
'badge' => __( 'Pro', 'wpforms-lite' ),
|
||||
'features_description' => __( 'Custom access to the following capabilities…', 'wpforms-lite' ),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,221 @@
|
||||
<?php
|
||||
namespace WPForms\Lite\Emails;
|
||||
|
||||
use WPForms\Lite\Reports\EntriesCount;
|
||||
use WPForms\Emails\Summaries as BaseSummaries;
|
||||
|
||||
/**
|
||||
* Email Summaries.
|
||||
*
|
||||
* @since 1.8.8
|
||||
*/
|
||||
class Summaries extends BaseSummaries {
|
||||
|
||||
/**
|
||||
* Whether counting entries is allowed for Lite users.
|
||||
*
|
||||
* @since 1.8.8
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $allow_entries_count_lite;
|
||||
|
||||
/**
|
||||
* Constructor for the class.
|
||||
* Initializes the object and registers the Lite weekly entries count cron schedule.
|
||||
*
|
||||
* @since 1.8.8
|
||||
*/
|
||||
public function __construct() {
|
||||
|
||||
// phpcs:disable WPForms.PHP.ValidateHooks.InvalidHookName
|
||||
|
||||
// Disabling this filter will prevent entries submission count from being updated.
|
||||
/** This filter is documented in /lite/wpforms-lite.php */
|
||||
$this->allow_entries_count_lite = apply_filters( 'wpforms_dash_widget_allow_entries_count_lite', true );
|
||||
|
||||
// phpcs:enable WPForms.PHP.ValidateHooks.InvalidHookName
|
||||
|
||||
parent::__construct();
|
||||
|
||||
// Register the Lite weekly entries count cron schedule.
|
||||
$this->register_entries_count_schedule();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hooks.
|
||||
*
|
||||
* @since 1.8.8
|
||||
*/
|
||||
public function hooks() {
|
||||
|
||||
parent::hooks();
|
||||
|
||||
// The following schedule is essential for the Lite version.
|
||||
// Regardless of the "Weekly Summaries" feature being disabled or enabled,
|
||||
// it ensures that entries numbers are consistently updated.
|
||||
if ( ! $this->allow_entries_count_lite ) {
|
||||
return;
|
||||
}
|
||||
|
||||
add_action( 'wpforms_weekly_entries_count_cron', [ $this, 'entries_count_cron' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts the Lite weekly entries count cron schedule.
|
||||
*
|
||||
* This function modifies the Lite weekly entries count cron schedule by reducing the interval by 5 seconds.
|
||||
*
|
||||
* @since 1.8.8
|
||||
* @deprecated 1.9.1
|
||||
*
|
||||
* @param array $schedules WP cron schedules.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function weekly_entries_count( $schedules ) {
|
||||
|
||||
_deprecated_function( __METHOD__, '1.9.1 of the WPForms plugin' );
|
||||
|
||||
$schedules['wpforms_weekly_entries_count'] = [
|
||||
'interval' => $this->get_next_launch_time() - time(),
|
||||
'display' => esc_html__( 'Calculate WPForms Lite Weekly Entries Count', 'wpforms-lite' ),
|
||||
];
|
||||
|
||||
return $schedules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the cron job to update entries count for Lite users.
|
||||
*
|
||||
* This function retrieves the current entries count for Lite users, calculates the count for the
|
||||
* previous week, and updates the necessary post meta data for trend calculations.
|
||||
*
|
||||
* @since 1.8.8
|
||||
*/
|
||||
public function entries_count_cron() {
|
||||
|
||||
// Get entries count for Lite users.
|
||||
$entries = ( new EntriesCount() )->get_by_form();
|
||||
|
||||
// Exit if there are no form entries to update.
|
||||
if ( empty( $entries ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ( $entries as $form_id => &$form ) {
|
||||
// Set total entries count to the current count.
|
||||
$form['total'] = $form['count'];
|
||||
|
||||
// Retrieve the previous week's count data from post meta.
|
||||
$previous_week_count = get_post_meta( $form_id, 'wpforms_entries_count_previous_week', true );
|
||||
|
||||
// Continue to the next form if the count data is not valid.
|
||||
if ( ! is_array( $previous_week_count ) || count( $previous_week_count ) !== 3 ) {
|
||||
$prev_count_previous_week = $form['total'];
|
||||
|
||||
// Set the previous week's count zero "0" if the form was published less than or equal to 7 days ago.
|
||||
if ( $this->is_form_created_in_7days( $form_id ) ) {
|
||||
$prev_count_previous_week = 0;
|
||||
}
|
||||
|
||||
update_post_meta( $form_id, 'wpforms_entries_count_previous_week', [ $form['total'], $form['total'], $prev_count_previous_week ] );
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
list( $total_previous_week, $count_previous_week ) = $previous_week_count;
|
||||
|
||||
// Calculate count, count_previous_week, and trends.
|
||||
$form['count'] = $form['total'] - $total_previous_week;
|
||||
|
||||
if ( count( array_unique( $previous_week_count ) ) === 1 ) {
|
||||
// If the previous week's count is the same as the current count, skip trends calculation.
|
||||
update_post_meta( $form_id, 'wpforms_entries_count_previous_week_skip_trends', true );
|
||||
} else {
|
||||
// If the previous week's count is different from the current count, calculate trends.
|
||||
delete_post_meta( $form_id, 'wpforms_entries_count_previous_week_skip_trends' );
|
||||
}
|
||||
|
||||
// Update post meta data for trend calculations.
|
||||
update_post_meta( $form_id, 'wpforms_entries_count_previous_week', [ $form['total'], $form['count'], $count_previous_week ] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get form entries.
|
||||
*
|
||||
* @since 1.8.8
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function get_entries(): array {
|
||||
|
||||
return ( new EntriesCount() )->get_form_trends();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register entries count schedule.
|
||||
*
|
||||
* @since 1.8.8
|
||||
*/
|
||||
private function register_entries_count_schedule() {
|
||||
|
||||
if ( ! $this->allow_entries_count_lite && wp_next_scheduled( 'wpforms_weekly_entries_count_cron' ) ) {
|
||||
wp_clear_scheduled_hook( 'wpforms_weekly_entries_count_cron' );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( $this->allow_entries_count_lite && ! wp_next_scheduled( 'wpforms_weekly_entries_count_cron' ) ) {
|
||||
// Since v1.9.1 we use a single event and manually reoccur it
|
||||
// because a recurring event cannot guarantee
|
||||
// its firing at the same time during WP_CLI execution.
|
||||
wp_schedule_single_event( $this->get_next_launch_time(), 'wpforms_weekly_entries_count_cron' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get next Monday midnight with WordPress offset.
|
||||
*
|
||||
* @since 1.9.1
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected function get_next_launch_time(): int {
|
||||
|
||||
$datetime = date_create( 'next monday', wp_timezone() );
|
||||
|
||||
if ( ! $datetime ) {
|
||||
return time() + WEEK_IN_SECONDS;
|
||||
}
|
||||
|
||||
return absint( $datetime->getTimestamp() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given form_id was published less than or equal to 7 days ago.
|
||||
*
|
||||
* @since 1.8.8
|
||||
*
|
||||
* @param int $form_id The ID of the form (post).
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_form_created_in_7days( int $form_id ): bool {
|
||||
|
||||
// Get the form (post) publish date.
|
||||
$date_created = get_post_field( 'post_date', $form_id, 'raw' );
|
||||
|
||||
// If the form date is not available, return false.
|
||||
if ( empty( $date_created ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Calculate the time difference between the post date and the current date.
|
||||
$time_difference = time() - strtotime( $date_created );
|
||||
|
||||
// Compare the time difference with 7 days in seconds.
|
||||
return $time_difference <= 7 * DAY_IN_SECONDS;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
namespace WPForms\Lite\Integrations\Abilities;
|
||||
|
||||
use WP_Error;
|
||||
use WPForms\Integrations\Abilities\Abilities as AbilitiesBase;
|
||||
|
||||
/**
|
||||
* WordPress Abilities API Integration for WPForms Lite.
|
||||
*
|
||||
* @since 1.9.9
|
||||
*/
|
||||
class Abilities extends AbilitiesBase {
|
||||
|
||||
/**
|
||||
* Register WPForms abilities for Lite version.
|
||||
*
|
||||
* @since 1.9.9
|
||||
*/
|
||||
public function register_abilities(): void {
|
||||
|
||||
// Register common abilities (list_forms, get_form).
|
||||
$this->register_common_abilities();
|
||||
|
||||
// Lite-specific: Register form stats ability (basic).
|
||||
$this->register_form_stats_ability();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the form_stats ability (Lite version - basic stats with upsell).
|
||||
*
|
||||
* @since 1.9.9
|
||||
*/
|
||||
protected function register_form_stats_ability(): void {
|
||||
|
||||
wp_register_ability(
|
||||
self::ABILITY_NAMESPACE . '/get-form-stats',
|
||||
[
|
||||
'label' => __( 'Get Form Stats', 'wpforms-lite' ),
|
||||
'description' => __( 'Get basic statistics for a WPForms form. Upgrade to Pro for detailed entry data.', 'wpforms-lite' ),
|
||||
'category' => self::CATEGORY_SLUG,
|
||||
'execute_callback' => [ $this, 'ability_get_form_stats' ],
|
||||
'permission_callback' => [ $this, 'check_view_single_form_permission' ],
|
||||
'input_schema' => [
|
||||
'type' => 'object',
|
||||
'properties' => [
|
||||
'form_id' => [
|
||||
'description' => __( 'The ID of the form to get stats for.', 'wpforms-lite' ),
|
||||
'type' => 'integer',
|
||||
'required' => true,
|
||||
'minimum' => 1,
|
||||
],
|
||||
],
|
||||
'required' => [ 'form_id' ],
|
||||
],
|
||||
'output_schema' => [
|
||||
'type' => 'object',
|
||||
'properties' => [
|
||||
'form_id' => [ 'type' => 'integer' ],
|
||||
'entries_available' => [ 'type' => 'boolean' ],
|
||||
'message' => [ 'type' => 'string' ],
|
||||
],
|
||||
],
|
||||
'meta' => [
|
||||
'annotations' => [
|
||||
'readonly' => true,
|
||||
'destructive' => false,
|
||||
'idempotent' => true,
|
||||
],
|
||||
'show_in_rest' => true,
|
||||
'mcp' => [
|
||||
'public' => true,
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ability callback: Get form stats (Lite version).
|
||||
*
|
||||
* @since 1.9.9
|
||||
*
|
||||
* @param mixed $input Input data.
|
||||
*
|
||||
* @return array|WP_Error
|
||||
*/
|
||||
public function ability_get_form_stats( $input = null ) {
|
||||
|
||||
$args = $this->normalize_input( $input );
|
||||
$form_id = absint( $args['form_id'] ?? 0 );
|
||||
|
||||
$form_handler = $this->get_form_handler();
|
||||
|
||||
if ( is_wp_error( $form_handler ) ) {
|
||||
return $form_handler;
|
||||
}
|
||||
|
||||
$form = $form_handler->get( $form_id );
|
||||
|
||||
if ( empty( $form ) ) {
|
||||
return new WP_Error(
|
||||
'wpforms_form_not_found',
|
||||
__( 'Form not found.', 'wpforms-lite' ),
|
||||
[ 'status' => 404 ]
|
||||
);
|
||||
}
|
||||
|
||||
// Lite version returns limited stats with the upsell message.
|
||||
return [
|
||||
'form_id' => $form_id,
|
||||
'entries_available' => false,
|
||||
'message' => __( 'Entry statistics require WPForms Pro. Upgrade to access detailed form submission data.', 'wpforms-lite' ),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace WPForms\Lite\Integrations\Elementor;
|
||||
|
||||
use WPForms\Integrations\Elementor\ThemesData as ThemesDataBase;
|
||||
|
||||
/**
|
||||
* Themes data for Gutenberg block for Lite.
|
||||
*
|
||||
* @since 1.9.6
|
||||
*/
|
||||
class ThemesData extends ThemesDataBase {
|
||||
|
||||
/**
|
||||
* WPForms themes JSON file path.
|
||||
*
|
||||
* Relative to the WPForms plugin directory.
|
||||
*
|
||||
* @since 1.9.6
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected const THEMES_WPFORMS_JSON_PATH = 'assets/lite/js/integrations/elementor/themes.json';
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
namespace WPForms\Lite\Integrations\Gutenberg;
|
||||
|
||||
use WPForms\Integrations\Gutenberg\FormSelector as FormSelectorBase;
|
||||
use WPForms\Integrations\Gutenberg\RestApi;
|
||||
|
||||
/**
|
||||
* Gutenberg block for Lite.
|
||||
*
|
||||
* @since 1.8.8
|
||||
*/
|
||||
class FormSelector extends FormSelectorBase {
|
||||
|
||||
/**
|
||||
* Load an integration.
|
||||
*
|
||||
* @since 1.8.8
|
||||
*/
|
||||
public function load() {
|
||||
|
||||
$this->themes_data_obj = new ThemesData();
|
||||
|
||||
parent::load();
|
||||
}
|
||||
|
||||
/**
|
||||
* Integration hooks.
|
||||
*
|
||||
* @since 1.8.8
|
||||
*/
|
||||
protected function hooks() {
|
||||
|
||||
add_action( 'rest_api_init', [ $this, 'init_rest' ] );
|
||||
|
||||
parent::hooks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize rest API.
|
||||
*
|
||||
* @since 1.8.8
|
||||
*/
|
||||
public function init_rest() {
|
||||
|
||||
if ( ! $this->rest_api_obj ) {
|
||||
$this->rest_api_obj = new RestApi( $this, $this->themes_data_obj );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register WPForms Gutenberg block styles.
|
||||
*
|
||||
* @since 1.8.8
|
||||
*/
|
||||
protected function register_styles() {
|
||||
|
||||
if ( ! is_admin() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
parent::register_styles();
|
||||
|
||||
// FontAwesome.
|
||||
wp_enqueue_style(
|
||||
'wpforms-font-awesome',
|
||||
WPFORMS_PLUGIN_URL . 'assets/lib/font-awesome/css/all.min.css',
|
||||
null,
|
||||
'7.0.1'
|
||||
);
|
||||
|
||||
// FontAwesome v4 compatibility shims.
|
||||
wp_enqueue_style(
|
||||
'wpforms-font-awesome-v4-shim',
|
||||
WPFORMS_PLUGIN_URL . 'assets/lib/font-awesome/css/v4-shims.min.css',
|
||||
null,
|
||||
'4.7.0'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load WPForms Gutenberg block scripts.
|
||||
*
|
||||
* @since 1.8.8
|
||||
*/
|
||||
public function enqueue_block_editor_assets() {
|
||||
|
||||
parent::enqueue_block_editor_assets();
|
||||
|
||||
$min = wpforms_get_min_suffix();
|
||||
|
||||
wp_enqueue_script(
|
||||
'wpforms-generic-utils',
|
||||
WPFORMS_PLUGIN_URL . "assets/js/share/utils{$min}.js",
|
||||
[ 'jquery' ],
|
||||
WPFORMS_VERSION,
|
||||
true
|
||||
);
|
||||
|
||||
if ( ! $this->is_legacy_block() ) {
|
||||
wp_enqueue_script(
|
||||
'wpforms-gutenberg-form-selector',
|
||||
WPFORMS_PLUGIN_URL . "assets/lite/js/integrations/gutenberg/formselector.es5{$min}.js",
|
||||
[ 'wp-blocks', 'wp-i18n', 'wp-element', 'jquery', 'wpforms-admin-education-core', 'wpforms-generic-utils' ],
|
||||
WPFORMS_VERSION,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
wp_localize_script(
|
||||
'wpforms-gutenberg-form-selector',
|
||||
'wpforms_gutenberg_form_selector',
|
||||
$this->get_localize_data()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace WPForms\Lite\Integrations\Gutenberg;
|
||||
|
||||
use WPForms\Integrations\Gutenberg\ThemesData as ThemesDataBase;
|
||||
|
||||
/**
|
||||
* Themes data for Gutenberg block for Lite.
|
||||
*
|
||||
* @since 1.8.8
|
||||
*/
|
||||
class ThemesData extends ThemesDataBase {
|
||||
|
||||
/**
|
||||
* WPForms themes JSON file path.
|
||||
*
|
||||
* Relative to WPForms plugin directory.
|
||||
*
|
||||
* @since 1.8.8
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const THEMES_WPFORMS_JSON_PATH = 'assets/lite/js/integrations/gutenberg/themes.json';
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
<?php
|
||||
|
||||
namespace WPForms\Lite\Integrations\LiteConnect;
|
||||
|
||||
use WPForms\Admin\Notice;
|
||||
use WPForms\Helpers\Transient;
|
||||
|
||||
/**
|
||||
* Handles admin functionalities and setup for the application.
|
||||
*
|
||||
* @since 1.10.0.1
|
||||
*/
|
||||
class Admin {
|
||||
|
||||
/**
|
||||
* Dismiss notice slug.
|
||||
*
|
||||
* @since 1.10.0.1
|
||||
*/
|
||||
private const DISMISS_NOTICE_SLUG = 'lite_connect_send_error_alert';
|
||||
|
||||
/**
|
||||
* Initializes the constructor and setup hooks.
|
||||
*
|
||||
* @since 1.10.0.1
|
||||
*/
|
||||
public function __construct() {
|
||||
|
||||
$this->hooks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers hooks to manage the display of notices on specific pages.
|
||||
*
|
||||
* @since 1.10.0.1
|
||||
*/
|
||||
private function hooks(): void {
|
||||
|
||||
// Reset expired dismissed notice to allow re-displaying after one week.
|
||||
add_filter( 'option_wpforms_admin_notices', [ $this, 'reset_expired_notice' ] );
|
||||
|
||||
// Display notices only on WPForms pages.
|
||||
if ( $this->is_notice_target_page() ) {
|
||||
// Display an admin notice if there are entries available to import.
|
||||
add_action( 'admin_notices', [ $this, 'display_error_notices' ] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the dismissed notice if it was dismissed more than a week ago.
|
||||
*
|
||||
* @since 1.10.0.1
|
||||
*
|
||||
* @param mixed $notices Dismissed notices option value.
|
||||
*
|
||||
* @return array Modified dismissed notices option value.
|
||||
*/
|
||||
public function reset_expired_notice( $notices ): array { // phpcs:ignore WPForms.PHP.HooksMethod.InvalidPlaceForAddingHooks
|
||||
|
||||
$notices = (array) $notices;
|
||||
|
||||
if ( ! isset( $notices[ self::DISMISS_NOTICE_SLUG ] ) ) {
|
||||
return $notices;
|
||||
}
|
||||
|
||||
$notice_time = $notices[ self::DISMISS_NOTICE_SLUG ]['time'] ?? 0;
|
||||
|
||||
if ( ( time() - $notice_time ) <= WEEK_IN_SECONDS ) {
|
||||
return $notices;
|
||||
}
|
||||
|
||||
Transient::delete( SendEntryTask::SEND_ERROR_KEY );
|
||||
|
||||
unset( $notices[ self::DISMISS_NOTICE_SLUG ] );
|
||||
|
||||
remove_filter( 'option_wpforms_admin_notices', [ $this, 'reset_expired_notice' ] );
|
||||
update_option( 'wpforms_admin_notices', $notices, true );
|
||||
add_filter( 'option_wpforms_admin_notices', [ $this, 'reset_expired_notice' ] );
|
||||
|
||||
return $notices;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display error notices for entry backup failures.
|
||||
*
|
||||
* @since 1.10.0.1
|
||||
*
|
||||
* @noinspection HtmlUnknownTarget
|
||||
*/
|
||||
public function display_error_notices(): void {
|
||||
|
||||
if ( ! self::has_repeated_errors() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
Notice::error(
|
||||
sprintf(
|
||||
wp_kses( /* translators: %s - WPForms support URL. */
|
||||
__( '<strong>Entry Backup Failures Detected</strong><br>Some entry backups may not have been saved. This is usually caused by a scheduling issue on your site. Please <a href="%s" target="_blank" rel="noopener noreferrer">contact Support</a> so we can help resolve it and ensure your entries are protected.', 'wpforms-lite' ),
|
||||
[
|
||||
'strong' => [],
|
||||
'br' => [],
|
||||
'a' => [
|
||||
'href' => [],
|
||||
'target' => [],
|
||||
'rel' => [],
|
||||
],
|
||||
]
|
||||
),
|
||||
esc_url(
|
||||
wpforms_utm_link(
|
||||
'https://wpforms.com/account/support/',
|
||||
'Admin',
|
||||
'Contact Support - Lite Connect Backup Failure'
|
||||
)
|
||||
)
|
||||
),
|
||||
[
|
||||
'dismiss' => Notice::DISMISS_GLOBAL,
|
||||
'slug' => self::DISMISS_NOTICE_SLUG,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if there are repeated errors in the cached error data.
|
||||
*
|
||||
* @since 1.10.0.1
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function has_repeated_errors(): bool {
|
||||
|
||||
$lite_connect_send_errors = Transient::get( SendEntryTask::SEND_ERROR_KEY );
|
||||
|
||||
if ( empty( $lite_connect_send_errors ) || ! is_array( $lite_connect_send_errors ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ( $lite_connect_send_errors as $errors ) {
|
||||
if ( count( $errors ) >= 4 ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the current page is the target page for displaying a notice.
|
||||
*
|
||||
* @since 1.10.0.1
|
||||
*
|
||||
* @return bool True if the current page is the target page, false otherwise.
|
||||
*/
|
||||
private function is_notice_target_page(): bool {
|
||||
|
||||
global $pagenow;
|
||||
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
$is_dashboard_page = $pagenow === 'index.php' && empty( $_GET['page'] );
|
||||
|
||||
return $is_dashboard_page || wpforms_is_admin_page( 'overview' ) || wpforms_is_admin_page( 'settings' );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
namespace WPForms\Lite\Integrations\LiteConnect;
|
||||
|
||||
use WPForms\Helpers\Crypto;
|
||||
|
||||
/**
|
||||
* Integration between Lite Connect API and WPForms Lite.
|
||||
*
|
||||
* @since 1.7.4
|
||||
*/
|
||||
class Integration extends \WPForms\Integrations\LiteConnect\Integration {
|
||||
|
||||
/**
|
||||
* Encrypt the form entry and submit it to the Lite Connect API.
|
||||
*
|
||||
* If the regular wp_remote_post() request fail for any reasons, then an
|
||||
* Action Scheduler task will be created to retry a couple of minutes later.
|
||||
*
|
||||
* @since 1.7.4
|
||||
*
|
||||
* @param array $entry_args The entry data.
|
||||
* @param array $form_data The form data.
|
||||
*
|
||||
* @return false|string
|
||||
*/
|
||||
public function submit( $entry_args, $form_data ) {
|
||||
|
||||
if ( ! is_array( $entry_args ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$entry_args['form_data'] = $form_data;
|
||||
|
||||
// Encrypt entry using the WPForms Crypto class.
|
||||
$entry_data = Crypto::encrypt( wp_json_encode( $entry_args ) );
|
||||
|
||||
// We have to start requesting site keys in ajax, turning on the LC functionality.
|
||||
// First, the request to the API server will be sent.
|
||||
// Second, the server will respond to our callback URL /wpforms/auth/key/nonce, and the site key will be stored in the DB.
|
||||
// Third, we have to get access via a separate HTTP request.
|
||||
$this->update_keys(); // Third request here.
|
||||
|
||||
// Submit entry to the Lite Connect API.
|
||||
$response = $this->add_form_entry( $this->auth['access_token'], $entry_args['form_id'], $entry_data );
|
||||
|
||||
// Confirm if entry has been added successfully to the Lite Connect API.
|
||||
if ( $response ) {
|
||||
$response = json_decode( $response, true );
|
||||
}
|
||||
|
||||
if ( isset( $response['error'] ) && $response['error'] === 'Access token is invalid or expired.' ) {
|
||||
// Force to re-generate access token in case it is invalid.
|
||||
$this->get_access_token( $this->get_site_key(), true );
|
||||
}
|
||||
|
||||
if ( ! isset( $response['status'] ) || $response['status'] !== 'success' ) {
|
||||
/**
|
||||
* If Lite Connect API is not available in the add_form_entry()
|
||||
* request above, then a task is created to run it later via Action
|
||||
* Scheduler.
|
||||
*/
|
||||
( new SendEntryTask() )->create( $entry_args['form_id'], $entry_data );
|
||||
}
|
||||
|
||||
// Increase the entries count if the entry has been added successfully.
|
||||
if ( isset( $response['status'] ) && $response['status'] === 'success' ) {
|
||||
$this->increase_entries_count( $entry_args['form_id'] );
|
||||
}
|
||||
|
||||
if ( ! empty( $response['error'] ) ) {
|
||||
wpforms_log(
|
||||
'Lite Connect: error submitting form entry',
|
||||
[
|
||||
'response' => $response,
|
||||
'entry_args' => $entry_args,
|
||||
],
|
||||
[
|
||||
'type' => [ 'error' ],
|
||||
'form_id' => $entry_args['form_id'],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increases the Lite Connect entries count.
|
||||
*
|
||||
* @since 1.7.4
|
||||
*
|
||||
* @param int|false $form_id The form ID.
|
||||
*/
|
||||
public function increase_entries_count( $form_id = false ) {
|
||||
|
||||
self::maybe_set_entries_count();
|
||||
|
||||
update_option( self::LITE_CONNECT_ENTRIES_COUNT_OPTION, self::get_entries_count() + 1 );
|
||||
|
||||
// Increase the form entries count.
|
||||
// It allows counting entries on per form level.
|
||||
if ( ! empty( $form_id ) ) {
|
||||
$count = self::get_form_entries_count( (int) $form_id );
|
||||
|
||||
update_post_meta( $form_id, self::LITE_CONNECT_FORM_ENTRIES_COUNT_META, ++$count );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
<?php
|
||||
|
||||
namespace WPForms\Lite\Integrations\LiteConnect;
|
||||
|
||||
/**
|
||||
* Class LiteConnect for WPForms Lite.
|
||||
*
|
||||
* @since 1.7.4
|
||||
*/
|
||||
class LiteConnect extends \WPForms\Integrations\LiteConnect\LiteConnect {
|
||||
|
||||
/**
|
||||
* The Integration object.
|
||||
*
|
||||
* @since 1.7.4
|
||||
*
|
||||
* @var Integration
|
||||
*/
|
||||
private $integration;
|
||||
|
||||
/**
|
||||
* Send Entry Task object.
|
||||
*
|
||||
* @since 1.7.4
|
||||
*
|
||||
* @var SendEntryTask
|
||||
*/
|
||||
private $send_entry_task;
|
||||
|
||||
/**
|
||||
* Whether Lite Connect is enabled.
|
||||
*
|
||||
* @since 1.7.4
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_enabled() {
|
||||
|
||||
// phpcs:disable WPForms.PHP.ValidateHooks.InvalidHookName
|
||||
|
||||
/**
|
||||
* Determine whether LiteConnect is enabled on the WPForms > Settings admin page.
|
||||
*
|
||||
* @since 1.7.4
|
||||
*
|
||||
* @param bool $is_enabled Is LiteConnect enabled on WPForms > Settings page?
|
||||
*/
|
||||
return (bool) apply_filters( 'wpforms_lite_integrations_lite_connect_is_enabled', wpforms_setting( self::SETTINGS_SLUG ) );
|
||||
|
||||
// phpcs:enable WPForms.PHP.ValidateHooks.InvalidHookName
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the integration.
|
||||
*
|
||||
* @since 1.7.4
|
||||
*/
|
||||
public function load() {
|
||||
|
||||
parent::load();
|
||||
|
||||
// Do not load if user doesn't have permissions to update settings.
|
||||
if ( ! wpforms_current_user_can( wpforms_get_capability_manage_options() ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Hooks.
|
||||
$this->hooks();
|
||||
|
||||
// Process any pending submissions to the API, even if the Lite Connect integration is disabled.
|
||||
$this->send_entry_task = new SendEntryTask();
|
||||
|
||||
// It won't load if the Lite Connect integration is not enabled.
|
||||
if ( ! self::is_enabled() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We always need to instance the Integration class as part of the load process for the Lite Connect integration.
|
||||
$this->integration = new Integration();
|
||||
|
||||
if ( is_admin() ) {
|
||||
new Admin();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hooks.
|
||||
*
|
||||
* @since 1.7.4
|
||||
*/
|
||||
private function hooks() {
|
||||
|
||||
// Add Lite Connect option to settings.
|
||||
add_filter( 'wpforms_settings_defaults', [ $this, 'settings_option' ] );
|
||||
|
||||
// Automatically save the timestamp when Lite Connect was enabled first time.
|
||||
add_filter( 'wpforms_update_settings', [ $this, 'update_enabled_settings' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add "Lite Connect: Enable Entry Backups" to the WPForms Lite settings.
|
||||
*
|
||||
* @since 1.7.4
|
||||
*
|
||||
* @param array $settings WPForms settings.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function settings_option( $settings ) {
|
||||
|
||||
$setting = [
|
||||
self::SETTINGS_SLUG => [
|
||||
'id' => self::SETTINGS_SLUG,
|
||||
'name' => esc_html__( 'Lite Connect', 'wpforms-lite' ),
|
||||
'label' => esc_html__( 'Enable Entry Backups', 'wpforms-lite' ),
|
||||
'type' => 'toggle',
|
||||
'is-important' => true,
|
||||
'control-class' => 'wpforms-setting-lite-connect-auto-save-toggle',
|
||||
'input-attr' => 'disabled',
|
||||
'desc-on' => sprintf(
|
||||
wp_kses( /* translators: %s - upgrade to WPForms Pro landing page URL. */
|
||||
__( '<strong>Your form entries are not being stored locally, but are backed up remotely.</strong> If you <a href="%s" target="_blank" rel="noopener noreferrer" class="wpforms-upgrade-modal">upgrade to WPForms PRO</a>, you can restore your entries and they’ll be available in the WordPress dashboard. Entry backups expire after 1 year.', 'wpforms-lite' ),
|
||||
[
|
||||
'a' => [
|
||||
'href' => [],
|
||||
'class' => [],
|
||||
'target' => [],
|
||||
'rel' => [],
|
||||
],
|
||||
'strong' => [],
|
||||
]
|
||||
),
|
||||
esc_url( wpforms_admin_upgrade_link( 'settings-lite-connect-enabled' ) )
|
||||
),
|
||||
'desc-off' => sprintf(
|
||||
wp_kses( /* translators: %s - upgrade to WPForms Pro landing page URL. */
|
||||
__( '<strong>Your form entries are not being stored in WordPress, and your entry backups are not active.</strong> If there\'s a problem with deliverability, you\'ll lose form entries. We recommend that you enable Entry Backups, especially if you\'re considering <a href="%s" target="_blank" rel="noopener noreferrer" class="wpforms-upgrade-modal">upgrading to WPForms PRO</a>.', 'wpforms-lite' ),
|
||||
[
|
||||
'a' => [
|
||||
'href' => [],
|
||||
'class' => [],
|
||||
'target' => [],
|
||||
'rel' => [],
|
||||
],
|
||||
'strong' => [],
|
||||
]
|
||||
),
|
||||
esc_url( wpforms_admin_upgrade_link( 'settings-lite-connect-disabled', 'Upgrade to WPForms Pro text Link' ) )
|
||||
),
|
||||
],
|
||||
];
|
||||
|
||||
$settings['general'] = wpforms_list_insert_after( $settings['general'], 'license-key', $setting );
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Automatically save the additional info when Lite Connect was enabled first time.
|
||||
*
|
||||
* @since 1.7.4
|
||||
*
|
||||
* @param array $settings WPForms settings.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function update_enabled_settings( $settings ) {
|
||||
|
||||
if ( empty( $settings[ self::SETTINGS_SLUG ] ) ) {
|
||||
return $settings;
|
||||
}
|
||||
|
||||
$since = self::SETTINGS_SLUG . '-since';
|
||||
$email = self::SETTINGS_SLUG . '-email';
|
||||
|
||||
if ( empty( $settings[ $since ] ) ) {
|
||||
$settings[ $since ] = time();
|
||||
}
|
||||
|
||||
if ( empty( $settings[ $email ] ) ) {
|
||||
$user = wp_get_current_user();
|
||||
$settings[ $email ] = $user && ! empty( $user->user_email ) ? $user->user_email : get_option( 'admin_email' );
|
||||
}
|
||||
|
||||
return $settings;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
<?php
|
||||
|
||||
namespace WPForms\Lite\Integrations\LiteConnect;
|
||||
|
||||
use WPForms\Helpers\Transient;
|
||||
use WPForms\Integrations\LiteConnect\API;
|
||||
use WPForms\Tasks\Meta;
|
||||
|
||||
/**
|
||||
* Class SendEntryTask.
|
||||
*
|
||||
* @since 1.7.4
|
||||
*/
|
||||
class SendEntryTask extends Integration {
|
||||
|
||||
/**
|
||||
* Task name.
|
||||
*
|
||||
* @since 1.7.4
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public const LITE_CONNECT_TASK = 'wpforms_lite_connect_send_entry';
|
||||
|
||||
/**
|
||||
* Transient cache error key.
|
||||
*
|
||||
* @since 1.10.0.1
|
||||
*/
|
||||
public const SEND_ERROR_KEY = 'lite_connect_send_entry_error';
|
||||
|
||||
/**
|
||||
* SendEntryTask constructor.
|
||||
*
|
||||
* @since 1.7.4
|
||||
*/
|
||||
public function __construct() {
|
||||
|
||||
parent::__construct();
|
||||
|
||||
$this->hooks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the hooks.
|
||||
*
|
||||
* @since 1.7.4
|
||||
*/
|
||||
private function hooks() {
|
||||
|
||||
// Process the tasks as needed.
|
||||
add_action( self::LITE_CONNECT_TASK, [ $this, 'process' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a task to submit the lite entry to the Lite Connect API via
|
||||
* Action Scheduler.
|
||||
*
|
||||
* @since 1.7.4
|
||||
*
|
||||
* @param int $form_id The form ID.
|
||||
* @param string $entry_data The entry data.
|
||||
*/
|
||||
public function create( $form_id, $entry_data ) {
|
||||
|
||||
$action_id = wpforms()->obj( 'tasks' )
|
||||
->create( self::LITE_CONNECT_TASK )
|
||||
->params( $form_id, $entry_data )
|
||||
->once( time() + wp_rand( 10, 60 ) * MINUTE_IN_SECONDS )
|
||||
->register();
|
||||
|
||||
if ( $action_id === null ) {
|
||||
wpforms_log(
|
||||
'Lite Connect: error creating the AS task',
|
||||
[
|
||||
'task' => self::LITE_CONNECT_TASK,
|
||||
],
|
||||
[ 'type' => [ 'error' ] ]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the task to submit the entry to the Lite Connect API via
|
||||
* Action Scheduler.
|
||||
*
|
||||
* @since 1.7.4
|
||||
*
|
||||
* @param int $meta_id The meta ID.
|
||||
*/
|
||||
public function process( $meta_id ) {
|
||||
|
||||
// Load task data.
|
||||
$params = ( new Meta() )->get( (int) $meta_id );
|
||||
|
||||
[ $form_id, $entry_data ] = $params->data;
|
||||
|
||||
// Grab the current access token. If a site key or access token is not available, then it recreates the task to run later.
|
||||
$access_token = $this->get_access_token( $this->get_site_key() );
|
||||
|
||||
if ( ! $access_token ) {
|
||||
$this->create( $form_id, $entry_data );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Submit an entry to the Lite Connect API.
|
||||
$response = ( new API() )->add_form_entry( $access_token, $form_id, $entry_data );
|
||||
|
||||
if ( $response ) {
|
||||
$response = json_decode( $response, true );
|
||||
}
|
||||
|
||||
$response = (array) $response;
|
||||
|
||||
if ( isset( $response['error'] ) && $response['error'] === 'Access token is invalid or expired.' ) {
|
||||
// Force to re-generate an access token in case it is invalid.
|
||||
$this->get_access_token( $this->get_site_key(), true );
|
||||
}
|
||||
|
||||
if ( ! empty( $response['error'] ) ) {
|
||||
wpforms_log(
|
||||
'Lite Connect: error submitting form entry (AS task)',
|
||||
[
|
||||
'response' => $response,
|
||||
'entry_data' => $entry_data,
|
||||
],
|
||||
[
|
||||
'type' => [ 'error' ],
|
||||
'form_id' => $form_id,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
$entry_key = hash( 'md5', $entry_data );
|
||||
$lite_connect_send_errors = Transient::get( self::SEND_ERROR_KEY );
|
||||
$lite_connect_send_errors = is_array( $lite_connect_send_errors ) ? $lite_connect_send_errors : [];
|
||||
$status = $response['status'] ?? 'error';
|
||||
|
||||
// Recreate the task if the request to the API fails for any reasons.
|
||||
if ( $status !== 'success' ) {
|
||||
$lite_connect_send_errors[ $entry_key ][] = time();
|
||||
|
||||
// Keep only 5 last failed times to avoid a too long array.
|
||||
$lite_connect_send_errors[ $entry_key ] = array_slice( $lite_connect_send_errors[ $entry_key ], -5 );
|
||||
|
||||
Transient::set( self::SEND_ERROR_KEY, $lite_connect_send_errors );
|
||||
|
||||
$this->create( $form_id, $entry_data );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
unset( $lite_connect_send_errors[ $entry_key ] );
|
||||
|
||||
Transient::set( self::SEND_ERROR_KEY, $lite_connect_send_errors );
|
||||
|
||||
// Increase the entries count if the entry has been added successfully.
|
||||
$this->increase_entries_count( $form_id );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
<?php
|
||||
|
||||
namespace WPForms\Lite\Reports;
|
||||
|
||||
/**
|
||||
* Generate form submissions reports.
|
||||
*
|
||||
* @since 1.5.4
|
||||
*/
|
||||
class EntriesCount {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @since 1.5.4
|
||||
*/
|
||||
public function __construct() {}
|
||||
|
||||
/**
|
||||
* Get entries count grouped by form.
|
||||
* Main point of entry to fetch form entry count data from DB.
|
||||
* Cache the result.
|
||||
*
|
||||
* @since 1.5.4
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_by_form() {
|
||||
|
||||
// Get form IDs.
|
||||
$forms = wpforms()->obj( 'form' )->get( '', [ 'fields' => 'ids' ] );
|
||||
|
||||
// Return early if no forms found.
|
||||
if ( empty( $forms ) || ! is_array( $forms ) ) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$results = [];
|
||||
|
||||
// Iterate through form IDs.
|
||||
foreach ( $forms as $form_id ) {
|
||||
// Get entries count for the form.
|
||||
$count = absint( get_post_meta( $form_id, 'wpforms_entries_count', true ) );
|
||||
|
||||
// Skip if the count is empty.
|
||||
if ( empty( $count ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add form details to the result.
|
||||
$results[ $form_id ] = [
|
||||
'form_id' => $form_id,
|
||||
'count' => $count,
|
||||
'title' => get_the_title( $form_id ),
|
||||
];
|
||||
}
|
||||
|
||||
// Sort forms by entries count (desc).
|
||||
if ( ! empty( $results ) ) {
|
||||
uasort(
|
||||
$results,
|
||||
function ( $a, $b ) {
|
||||
return ( $a['count'] > $b['count'] ) ? -1 : 1;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve and calculate form trends data for Lite users.
|
||||
*
|
||||
* This function calculates and returns trends data for Lite users based on the total number
|
||||
* of entries submitted per week compared to the previous week's total entries. Optionally
|
||||
* updates the database with the calculated data.
|
||||
*
|
||||
* @since 1.8.8
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_form_trends() {
|
||||
|
||||
// Get form IDs.
|
||||
$results = $this->get_by_form();
|
||||
|
||||
// Collection of form IDs that don't have valid previous week's count data.
|
||||
$maybe_unset_form_ids = [];
|
||||
|
||||
foreach ( $results as $form_id => &$form ) {
|
||||
// Retrieve the previous week's count data from post meta.
|
||||
$previous_week_count = get_post_meta( $form_id, 'wpforms_entries_count_previous_week', true );
|
||||
|
||||
// Continue to the next form if the count data is not valid.
|
||||
if ( ! is_array( $previous_week_count ) || count( $previous_week_count ) !== 3 ) {
|
||||
$maybe_unset_form_ids[] = $form_id;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Continue to the next form if the previous week's count data is not valid.
|
||||
if ( count( array_unique( $previous_week_count ) ) === 1 ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
list( $total_previous_week, $count_previous_week, $prev_count_previous_week ) = $previous_week_count;
|
||||
|
||||
// Calculate the form's trends data.
|
||||
$form['total'] = $total_previous_week + $count_previous_week;
|
||||
$form['count'] = $form['total'] - $total_previous_week;
|
||||
$form['count_previous_week'] = $prev_count_previous_week;
|
||||
|
||||
// If both the current week's count and the previous week's count are zero, set trends to zero.
|
||||
if ( $form['count_previous_week'] === 0 && $form['count'] === 0 ) {
|
||||
$form['trends'] = 0;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// If trends are set to be skipped, set trends to zero, and set the previous week's count to zero.
|
||||
// Thies's been needed since at this stage we don't know the number of entries submitted in the previous week.
|
||||
if ( (bool) get_post_meta( $form_id, 'wpforms_entries_count_previous_week_skip_trends', true ) ) {
|
||||
$form['trends'] = 0;
|
||||
$form['count_previous_week'] = 0;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$form['trends'] = $this->get_calculated_trends( $form['count'], $form['count_previous_week'] );
|
||||
}
|
||||
|
||||
// Unset forms that don't have valid previous week's count data.
|
||||
return $this->maybe_unset_form_ids( $results, $maybe_unset_form_ids );
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsets forms from the results array that lack valid previous week's count data.
|
||||
*
|
||||
* This function checks for the presence of valid previous week's count data for each form in the
|
||||
* provided results array. If all forms in the array lack valid data, the original results array is
|
||||
* returned without any changes. Otherwise, forms without valid data are unset from the array.
|
||||
*
|
||||
* @since 1.8.8
|
||||
*
|
||||
* @param array $results The original array of form results.
|
||||
* @param array $maybe_unset_form_ids The form IDs that may need to be unset.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function maybe_unset_form_ids( $results, $maybe_unset_form_ids ) {
|
||||
|
||||
if ( empty( $maybe_unset_form_ids ) ) {
|
||||
return $results;
|
||||
}
|
||||
|
||||
// If all forms don't have valid previous week's count data, return early.
|
||||
if ( count( $maybe_unset_form_ids ) === count( $results ) ) {
|
||||
return $results;
|
||||
}
|
||||
|
||||
// Unset forms that don't have valid previous week's count data.
|
||||
foreach ( $maybe_unset_form_ids as $form_id ) {
|
||||
unset( $results[ $form_id ] );
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the calculated trends based on the count and count from the previous week.
|
||||
*
|
||||
* This function calculates and returns the trends based on the current count
|
||||
* and the count from the previous week.
|
||||
*
|
||||
* @since 1.8.8
|
||||
*
|
||||
* @param int $count The current count.
|
||||
* @param int $count_previous_week The count from the previous week.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function get_calculated_trends( $count, $count_previous_week ) {
|
||||
|
||||
// If count from the previous week is zero, set trends to 100 to avoid division by zero.
|
||||
return ( $count_previous_week === 0 ) ? 100 : round( ( $count - $count_previous_week ) / $count_previous_week * 100 );
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user