=' ) ); /** * Defines the minimum version of WordPress that will be officially supported. * * @var string GF_MIN_WP_VERSION_SUPPORT_TERMS The version number */ define( 'GF_MIN_WP_VERSION_SUPPORT_TERMS', '5.5' ); if ( ! defined( 'GRAVITY_MANAGER_URL' ) ) { /** * Defines the Gravity Manager URL. * * @var string GRAVITY_MANAGER_URL The full URL to the Gravity Manager. */ define( 'GRAVITY_MANAGER_URL', 'https://gravityapi.com/wp-content/plugins/gravitymanager' ); } require_once( plugin_dir_path( __FILE__ ) . 'currency.php' ); require_once( plugin_dir_path( __FILE__ ) . 'common.php' ); require_once( plugin_dir_path( __FILE__ ) . 'forms_model.php' ); require_once( plugin_dir_path( __FILE__ ) . 'widget.php' ); require_once( plugin_dir_path( __FILE__ ) . 'includes/api.php' ); require_once( plugin_dir_path( __FILE__ ) . 'includes/webapi/webapi.php' ); require_once( plugin_dir_path( __FILE__ ) . 'includes/fields/class-gf-fields.php' ); require_once( plugin_dir_path( __FILE__ ) . 'includes/class-gf-download.php' ); require_once( plugin_dir_path( __FILE__ ) . 'includes/query/class-gf-query.php' ); // Load Logging if Logging Add-On is not active. if ( ! GFCommon::is_logging_plugin_active() ) { require_once( plugin_dir_path( __FILE__ ) . 'includes/logging/logging.php' ); } // GFCommon::$version is deprecated, set it to current version for backwards compatibility GFCommon::$version = GFForms::$version; add_action( 'init', array( 'GFForms', 'init' ) ); add_action( 'wp', array( 'GFForms', 'maybe_process_form' ), 9 ); add_action( 'admin_init', array( 'GFForms', 'maybe_process_form' ), 9 ); add_action( 'wp', array( 'GFForms', 'process_exterior_pages' ) ); add_action( 'admin_init', array( 'GFForms', 'process_exterior_pages' ) ); add_action( 'wp_ajax_update_auto_update_setting', array( 'GFForms', 'update_auto_update_setting' ) ); add_filter( 'upgrader_pre_install', array( 'GFForms', 'validate_upgrade' ), 10, 2 ); add_filter( 'tiny_mce_before_init', array( 'GFForms', 'modify_tiny_mce_4' ), 20 ); add_filter( 'user_has_cap', array( 'RGForms', 'user_has_cap' ), 10, 3 ); add_filter( 'query', array( 'GFForms', 'filter_query' ) ); add_filter( 'plugin_auto_update_setting_html', array( 'GFForms', 'auto_update_message' ), 10, 3 ); add_filter( 'plugin_auto_update_debug_string', array( 'GFForms', 'auto_update_debug_message' ), 10, 4 ); //Hooks for no-conflict functionality if ( is_admin() && ( GFForms::is_gravity_page() || GFForms::is_gravity_ajax_action() ) ) { add_action( 'wp_print_scripts', array( 'GFForms', 'no_conflict_mode_script' ), 1000 ); add_action( 'admin_print_footer_scripts', array( 'GFForms', 'no_conflict_mode_script' ), 9 ); add_action( 'wp_print_styles', array( 'GFForms', 'no_conflict_mode_style' ), 1000 ); add_action( 'admin_print_styles', array( 'GFForms', 'no_conflict_mode_style' ), 1 ); add_action( 'admin_print_footer_scripts', array( 'GFForms', 'no_conflict_mode_style' ), 1 ); add_action( 'admin_footer', array( 'GFForms', 'no_conflict_mode_style' ), 1 ); } add_action( 'plugins_loaded', array( 'GFForms', 'loaded' ) ); register_activation_hook( __FILE__, array( 'GFForms', 'activation_hook' ) ); register_deactivation_hook( __FILE__, array( 'GFForms', 'deactivation_hook' ) ); gf_upgrade(); /** * Class GFForms * * Handles the loading of Gravity Forms and other core functionality */ class GFForms { /** * Defines this version of Gravity Forms. * * @since Unknown * @access public * * @var string $version The version number. */ public static $version = '2.4.22'; /** * Handles background upgrade tasks. * * @var GF_Background_Upgrader */ public static $background_upgrader = null; /** * Runs after Gravity Forms is loaded. * * Initializes add-ons. * * @since Unknown * @access public * * @uses GFAddOn::init_addons() * * @return void */ public static function loaded() { /** * Fires when Gravity Forms has loaded. * * When developing Add-Ons, use this hook to initialize any functionality that depends on Gravity Forms functionality. */ do_action( 'gform_loaded' ); //initializing Add-Ons if necessary if ( class_exists( 'GFAddOn' ) ) { GFAddOn::init_addons(); } if ( defined( 'OSDXP_DASHBOARD_VER' ) ) { // Integration with osDXP. require_once plugin_dir_path( __FILE__ ) . 'includes/class-gf-osdxp.php'; } } /** * Determines if the 3rd party Members plugin is active. * * @since 2.4.13 Removed Members v1 support. * @since Unknown * * @param null $deprecated No longer used. Previously the minimum version number of Members plugin to check for. * * @return boolean True if the Members plugin is active. False otherwise. */ public static function has_members_plugin( $deprecated = null ) { return function_exists( 'members_register_cap_group' ) && function_exists( 'members_register_cap' ); } /** * Initializes Gravity Forms. * * @since Unknown * @access public * * @return void */ public static function init() { if ( ! wp_next_scheduled( 'gravityforms_cron' ) ) { wp_schedule_event( time(), 'daily', 'gravityforms_cron' ); } add_action( 'gravityforms_cron', array( 'GFForms', 'cron' ) ); GF_Download::maybe_process(); //load text domains GFCommon::load_gf_text_domain( 'gravityforms' ); add_filter( 'gform_logging_supported', array( 'GFForms', 'set_logging_supported' ) ); add_action( 'admin_head', array( 'GFCommon', 'maybe_output_gf_vars' ) ); add_action( 'admin_head', array( 'GFForms', 'load_admin_bar_styles' ) ); add_action( 'wp_head', array( 'GFForms', 'load_admin_bar_styles' ) ); self::register_scripts(); self::init_background_upgrader(); // Run background feed processing. require_once( plugin_dir_path( __FILE__ ) . 'includes/addon/class-gf-feed-processor.php' ); gf_feed_processor(); // Maybe set up Gravity Forms if ( ( false === ( defined( 'DOING_AJAX' ) && true === DOING_AJAX ) ) ) { gf_upgrade()->maybe_upgrade(); } // Load Editor Blocks if WordPress is 5.0+. if ( function_exists( 'register_block_type' ) ) { // Load block framework. if ( ! class_exists( 'GF_Blocks' ) ) { require_once plugin_dir_path( __FILE__ ) . 'includes/blocks/class-gf-blocks.php'; } // Load included Blocks. GFCommon::glob_require_once( '/includes/blocks/class-gf-block-*.php' ); } // Plugin update actions add_filter( 'transient_update_plugins', array( 'GFForms', 'check_update' ) ); add_filter( 'site_transient_update_plugins', array( 'GFForms', 'check_update' ) ); add_filter( 'auto_update_plugin', array( 'GFForms', 'maybe_auto_update' ), 10, 2 ); if ( IS_ADMIN ) { global $current_user; //Members plugin integration. Adding Gravity Forms roles to the checkbox list if ( self::has_members_plugin() ) { add_action( 'members_register_cap_groups', array( 'GFForms', 'members_register_cap_group' ) ); add_action( 'members_register_caps', array( 'GFForms', 'members_register_caps' ) ); } // User Role Editor integration. add_filter( 'ure_capabilities_groups_tree', array( 'GFForms', 'filter_ure_capabilities_groups_tree' ) ); add_filter( 'ure_custom_capability_groups', array( 'GFForms', 'filter_ure_custom_capability_groups' ), 10, 2 ); if ( is_multisite() ) { add_filter( 'wpmu_drop_tables', array( 'GFFormsModel', 'mu_drop_tables' ) ); } add_action( 'admin_enqueue_scripts', array( 'GFForms', 'enqueue_admin_scripts' ) ); add_action( 'print_media_templates', array( 'GFForms', 'action_print_media_templates' ) ); if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { add_action( 'admin_footer', array( 'GFForms', 'deprecate_add_on_methods' ) ); } //Loading Gravity Forms if user has access to any functionality if ( GFCommon::current_user_can_any( GFCommon::all_caps() ) ) { require_once( GFCommon::get_base_path() . '/export.php' ); GFExport::maybe_export(); //Imports theme forms if configured to be automatic imported gf_upgrade()->maybe_import_theme_forms(); //creates the "Forms" left menu add_action( 'admin_menu', array( 'GFForms', 'create_menu' ) ); // Add site-wide admin notices add_action( 'admin_notices', array( 'GFForms', 'action_admin_notices' ) ); if ( GF_SUPPORTED_WP_VERSION ) { add_action( 'admin_footer', array( 'GFForms', 'check_upload_folder' ) ); add_action( 'wp_dashboard_setup', array( 'GFForms', 'dashboard_setup' ) ); // Support modifying the admin page title for settings add_filter( 'admin_title', array( __class__, 'modify_admin_title' ), 10, 2 ); // Display admin notice if logging is enabled. add_action( 'admin_notices', array( 'GFForms', 'maybe_display_logging_notice' ) ); require_once( GFCommon::get_base_path() . '/includes/locking/locking.php' ); if ( self::is_gravity_page() ) { require_once( GFCommon::get_base_path() . '/tooltips.php' ); } elseif ( RG_CURRENT_PAGE == 'media-upload.php' ) { require_once( GFCommon::get_base_path() . '/entry_list.php' ); } elseif ( in_array( RG_CURRENT_PAGE, array( 'admin.php', 'admin-ajax.php' ) ) ) { add_action( 'wp_ajax_rg_save_form', array( 'GFForms', 'save_form' ) ); add_action( 'wp_ajax_rg_change_input_type', array( 'GFForms', 'change_input_type' ) ); add_action( 'wp_ajax_rg_refresh_field_preview', array( 'GFForms', 'refresh_field_preview' ) ); add_action( 'wp_ajax_rg_add_field', array( 'GFForms', 'add_field' ) ); add_action( 'wp_ajax_rg_duplicate_field', array( 'GFForms', 'duplicate_field' ) ); add_action( 'wp_ajax_rg_delete_field', array( 'GFForms', 'delete_field' ) ); add_action( 'wp_ajax_rg_delete_file', array( 'GFForms', 'delete_file' ) ); add_action( 'wp_ajax_rg_select_export_form', array( 'GFForms', 'select_export_form' ) ); add_action( 'wp_ajax_rg_start_export', array( 'GFForms', 'start_export' ) ); add_action( 'wp_ajax_gf_upgrade_license', array( 'GFForms', 'upgrade_license' ) ); add_action( 'wp_ajax_gf_delete_custom_choice', array( 'GFForms', 'delete_custom_choice' ) ); add_action( 'wp_ajax_gf_save_custom_choice', array( 'GFForms', 'save_custom_choice' ) ); add_action( 'wp_ajax_gf_get_post_categories', array( 'GFForms', 'get_post_category_values' ) ); add_action( 'wp_ajax_gf_get_address_rule_values_select', array( 'GFForms', 'get_address_rule_values_select' ) ); add_action( 'wp_ajax_gf_get_notification_post_categories', array( 'GFForms', 'get_notification_post_category_values' ) ); //add_action( 'wp_ajax_gf_save_confirmation', array( 'GFForms', 'save_confirmation' ) ); add_action( 'wp_ajax_gf_delete_confirmation', array( 'GFForms', 'delete_confirmation' ) ); add_action( 'wp_ajax_gf_save_new_form', array( 'GFForms', 'save_new_form' ) ); add_action( 'wp_ajax_gf_save_title', array( 'GFForms', 'save_form_title' ) ); //entry list ajax operations add_action( 'wp_ajax_rg_update_lead_property', array( 'GFForms', 'update_lead_property' ) ); add_action( 'wp_ajax_delete-gf_entry', array( 'GFForms', 'update_lead_status' ) ); //form list ajax operations add_action( 'wp_ajax_rg_update_form_active', array( 'GFForms', 'update_form_active' ) ); //notification list ajax operations add_action( 'wp_ajax_rg_update_notification_active', array( 'GFForms', 'update_notification_active' ) ); //confirmation list ajax operations add_action( 'wp_ajax_rg_update_confirmation_active', array( 'GFForms', 'update_confirmation_active' ) ); //dynamic captcha image add_action( 'wp_ajax_rg_captcha_image', array( 'GFForms', 'captcha_image' ) ); //dashboard message "dismiss upgrade" link add_action( 'wp_ajax_rg_dismiss_upgrade', array( 'GFForms', 'dashboard_dismiss_upgrade' ) ); // entry detail: resend notifications add_action( 'wp_ajax_gf_resend_notifications', array( 'GFForms', 'resend_notifications' ) ); // Shortcode UI add_action( 'wp_ajax_gf_do_shortcode', array( 'GFForms', 'handle_ajax_do_shortcode' ) ); // Export add_filter( 'wp_ajax_gf_process_export', array( 'GFForms', 'ajax_process_export' ) ); add_filter( 'wp_ajax_gf_download_export', array( 'GFForms', 'ajax_download_export' ) ); // Dismiss message add_action( 'wp_ajax_gf_dismiss_message', array( 'GFForms', 'ajax_dismiss_message' ) ); // Check background tasks for the system report add_action( 'wp_ajax_gf_check_background_tasks', array( 'GFForms', 'check_background_tasks' ) ); // Check status of upgrade add_action( 'wp_ajax_gf_force_upgrade', array( 'GFForms', 'ajax_force_upgrade' ) ); // Disable logging. add_action( 'wp_ajax_gf_disable_logging', array( 'GFForms', 'ajax_disable_logging' ) ); // Get change log. add_action( 'wp_ajax_gf_get_changelog', array( 'GFForms', 'ajax_display_changelog' ) ); } add_filter( 'plugins_api', array( 'GFForms', 'get_addon_info' ), 100, 3 ); add_action( 'after_plugin_row', array( 'GFForms', 'plugin_row' ), 10, 2 ); add_action( 'in_plugin_update_message-gravityforms/gravityforms.php', array( 'GFForms', 'in_plugin_update_message' ), 10, 2 ); add_action( 'install_plugins_pre_plugin-information', array( 'GFForms', 'display_changelog' ), 9 ); add_filter( 'plugin_action_links', array( 'GFForms', 'plugin_settings_link' ), 10, 2 ); } } add_action( 'admin_init', array( 'GFForms', 'ajax_parse_request' ), 10 ); $gf_page = self::get_page(); if ( $gf_page == 'entry_list' && ! isset( $_GET['filter'] ) ) { require_once( GFCommon::get_base_path() . '/entry_list.php' ); $default_filter = GFEntryList::get_default_filter(); if ( $default_filter !== 'all' ) { $url = add_query_arg( array( 'filter' => $default_filter ) ); $url = esc_url_raw( $url ); wp_safe_redirect( $url ); } } if ( $gf_page == 'entry_list' ) { add_filter( 'screen_settings', array( 'GFForms', 'show_screen_options' ), 10, 2 ); // For WP 5.4.1 and older. add_filter( 'set-screen-option', array( 'GFForms', 'set_screen_options' ), 10, 3 ); // For WP 5.4.2+. add_filter( 'set_screen_option_gform_entries_screen_options', array( 'GFForms', 'set_screen_options', ), 10, 3 ); } if ( $gf_page == 'form_list' ) { // For WP 5.4.1 and older. add_filter( 'set-screen-option', array( 'GFForms', 'set_screen_options' ), 10, 3 ); // For WP 5.4.2+. add_filter( 'set_screen_option_gform_forms_per_page', array( 'GFForms', 'set_screen_options' ), 10, 3 ); } add_filter( 'wp_privacy_personal_data_exporters', array( 'GFForms', 'register_data_exporter' ), 10 ); add_filter( 'wp_privacy_personal_data_erasers', array( 'GFForms', 'register_data_eraser' ), 10 ); } else { add_action( 'wp_enqueue_scripts', array( 'GFForms', 'enqueue_scripts' ), 11 ); add_action( 'wp', array( 'GFForms', 'ajax_parse_request' ), 10 ); } // Add admin bar items add_action( 'wp_before_admin_bar_render', array( 'GFForms', 'admin_bar' ) ); add_shortcode( 'gravityform', array( 'GFForms', 'parse_shortcode' ) ); add_shortcode( 'gravityforms', array( 'GFForms', 'parse_shortcode' ) ); // ManageWP premium update filters add_filter( 'mwp_premium_update_notification', array( 'GFForms', 'premium_update_push' ) ); add_filter( 'mwp_premium_perform_update', array( 'GFForms', 'premium_update' ) ); // Push Gravity Forms to the top of the list of plugins to make sure it's loaded before any add-ons add_action( 'activated_plugin', array( 'GFForms', 'load_first' ) ); // Add the "Add Form" button to the editor. The customizer doesn't run in the admin context. if ( GFForms::page_supports_add_form_button() ) { require_once( GFCommon::get_base_path() . '/tooltips.php' ); // Adding "embed form" button to the editor add_action( 'media_buttons', array( 'GFForms', 'add_form_button' ), 20 ); // Adding the modal add_action( 'admin_print_footer_scripts', array( 'GFForms', 'add_mce_popup' ) ); } } /** * Ensures that Gravity Forms is loaded first. * * @since Unknown * @access public * * @return void */ public static function load_first() { $plugin_path = basename( dirname( __FILE__ ) ) . '/gravityforms.php'; $active_plugins = array_values( maybe_unserialize( self::get_wp_option( 'active_plugins' ) ) ); $key = array_search( $plugin_path, $active_plugins ); if ( $key > 0 ) { array_splice( $active_plugins, $key, 1 ); array_unshift( $active_plugins, $plugin_path ); update_option( 'active_plugins', $active_plugins ); } } /** * Performs Gravity Forms deactivation tasks. * * @since Unknown * @access public * * @uses GFCache::flush() * * @return void */ public static function deactivation_hook() { GFCache::flush( true ); flush_rewrite_rules(); } /** * Performs Gravity Forms activation tasks. * * @since 2.3 * @access public */ public static function activation_hook() { self::init_background_upgrader(); gf_upgrade()->maybe_upgrade(); } /** * Add Gravity Forms to the plugins that support logging. * * @since Unknown * @access public * * @param array $plugins Existing plugins that support logging. * * @return array $plugins Supported plugins. */ public static function set_logging_supported( $plugins ) { $plugins['gravityformsapi'] = 'Gravity Forms API'; $plugins['gravityforms'] = 'Gravity Forms Core'; return $plugins; } /** * Gets the value of an option from the wp_options table. * * @since Unknown * @access public * @global $wpdb * * @param string $option_name The option to find. * * @return string The option value, if found. */ public static function get_wp_option( $option_name ) { global $wpdb; return $wpdb->get_var( $wpdb->prepare( "SELECT option_value FROM {$wpdb->prefix}options WHERE option_name=%s", $option_name ) ); } /** * Determines if a form should be processed, and passes it off to processing. * * @since Unknown * @access public * * @uses GFFormsModel::get_form() * @uses GFCommon::get_base_path() * @uses GFFormDisplay::process_form() * @uses GFFormDisplay::process_send_resume_link() * * @return void */ public static function maybe_process_form() { if ( isset( $_POST['gform_send_resume_link'] ) ) { require_once( GFCommon::get_base_path() . '/form_display.php' ); GFFormDisplay::process_send_resume_link(); } elseif ( isset( $_POST['gform_submit'] ) ) { require_once( GFCommon::get_base_path() . '/form_display.php' ); $form_id = GFFormDisplay::is_submit_form_id_valid(); if ( $form_id ) { GFFormDisplay::process_form( $form_id ); } } } /** * Processes pages that are not loaded directly within WordPress * * @since Unknown * @access public * * @uses GFCommon::get_upload_page_slug() * @uses GFCommon::get_base_path() * * @return void */ public static function process_exterior_pages() { if ( rgempty( 'gf_page', $_GET ) ) { return; } $page = rgget( 'gf_page' ); $is_legacy_upload_page = $_SERVER['REQUEST_METHOD'] == 'POST' && $page == 'upload'; if ( $is_legacy_upload_page && ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX ) ) { _doing_it_wrong( 'gf_page=upload', 'gf_page=upload is now deprecated. Use GFCommon::get_upload_page_slug() instead', '1.9.6.13' ); } $is_upload_page = $_SERVER['REQUEST_METHOD'] == 'POST' && $page == GFCommon::get_upload_page_slug(); if ( $is_upload_page || $is_legacy_upload_page ) { require_once( GFCommon::get_base_path() . '/includes/upload.php' ); exit(); } // Ensure users are logged in if ( ! is_user_logged_in() ) { auth_redirect(); } switch ( $page ) { case 'preview': require_once( GFCommon::get_base_path() . '/preview.php' ); break; case 'print-entry' : require_once( GFCommon::get_base_path() . '/print-entry.php' ); break; case 'select_columns' : require_once( GFCommon::get_base_path() . '/select_columns.php' ); break; } exit(); } /** * Checks for Gravity Forms updates. * * @since Unknown * @access public * * @uses GFCommon::check_update() * * @param GFAutoUpgrade $update_plugins_option The GFAutoUpgrade object. * * @return GFAutoUpgrade The GFAutoUpgrade object. */ public static function check_update( $update_plugins_option ) { if ( ! class_exists( 'GFCommon' ) ) { require_once( 'common.php' ); } return GFCommon::check_update( $update_plugins_option, true ); } /** * Adds index and htaccess files to the upload root for security. * * @since Unknown * @access public * * @return void */ public static function add_security_files() { GFCommon::log_debug( __METHOD__ . '(): Start adding security files' ); $upload_root = GFFormsModel::get_upload_root(); if ( ! is_dir( $upload_root ) ) { return; } GFCommon::recursive_add_index_file( $upload_root ); GFCommon::add_htaccess_file(); } /** * Self-heals suspicious files. * * @since Unknown */ private static function do_self_healing() { GFCommon::log_debug( __METHOD__ . '(): Start self healing' ); $gf_upload_root = GFFormsModel::get_upload_root(); if ( ! is_dir( $gf_upload_root ) || is_link( $gf_upload_root ) ) { return; } self::rename_suspicious_files_recursive( $gf_upload_root ); } /** * Renames files with a .bak extension if they have a file extension that is not allowed in the Gravity Forms uploads folder. * * @since Unknown * @access private * * @used-by GFForms::do_self_healing() * * @param string $dir The path to process. */ private static function rename_suspicious_files_recursive( $dir ) { if ( ! is_dir( $dir ) || is_link( $dir ) ) { return; } if ( ! ( $dir_handle = opendir( $dir ) ) ) { return; } // Ignores all errors set_error_handler( '__return_false', E_ALL ); while ( false !== ( $file = readdir( $dir_handle ) ) ) { if ( is_dir( $dir . DIRECTORY_SEPARATOR . $file ) && $file != '.' && $file != '..' ) { self::rename_suspicious_files_recursive( $dir . DIRECTORY_SEPARATOR . $file ); } elseif ( GFCommon::file_name_has_disallowed_extension( $file ) && ! GFCommon::match_file_extension( $file, array( 'htaccess', 'bak', 'html' ) ) ) { $mini_hash = substr( wp_hash( $file ), 0, 6 ); $newName = sprintf( '%s/%s.%s.bak', $dir, $file, $mini_hash ); rename( $dir . '/' . $file, $newName ); } } // Restores error handler restore_error_handler(); closedir( $dir_handle ); return; } /** * Renames suspicious content within the wp_upload directory. * * @deprecated 2.4.11 * * @since Unknown */ private static function heal_wp_upload_dir() { _deprecated_function( 'heal_wp_upload_dir', '2.4.11' ); $wp_upload_dir = wp_upload_dir(); $wp_upload_path = $wp_upload_dir['basedir']; if ( ! is_dir( $wp_upload_path ) || is_link( $wp_upload_path ) ) { return; } // ignores all errors set_error_handler( '__return_false', E_ALL ); foreach ( glob( $wp_upload_path . DIRECTORY_SEPARATOR . '*_input_*.php' ) as $filename ) { $mini_hash = substr( wp_hash( $filename ), 0, 6 ); $newName = sprintf( '%s.%s.bak', $filename, $mini_hash ); rename( $filename, $newName ); } // restores error handler restore_error_handler(); return; } /** * Defines styles needed for "no conflict mode" * * @since Unknown * @access public * @global $wp_styles * * @uses GFForms::no_conflict_mode() */ public static function no_conflict_mode_style() { if ( ! get_option( 'gform_enable_noconflict' ) ) { return; } global $wp_styles; $wp_required_styles = array( 'admin-bar', 'colors', 'ie', 'wp-admin', 'editor-style' ); $gf_required_styles = array( 'common' => array( 'gform_tooltip', 'gform_font_awesome', 'gform_admin' ), 'gf_edit_forms' => array( 'thickbox', 'editor-buttons', 'wp-jquery-ui-dialog', 'media-views', 'buttons', 'wp-pointer', 'gform_chosen', ), 'gf_edit_forms_settings' => array( 'thickbox', 'editor-buttons', 'wp-jquery-ui-dialog', 'media-views', 'buttons', ), 'gf_new_form' => array( 'thickbox' ), 'gf_entries' => array( 'thickbox', 'gform_chosen' ), 'gf_settings' => array(), 'gf_export' => array(), 'gf_help' => array(), 'gf_system_status' => array( 'thickbox' ), ); self::no_conflict_mode( $wp_styles, $wp_required_styles, $gf_required_styles, 'styles' ); } /** * Defines scripts needed for "no conflict mode". * * @since Unknown * @access public * @global $wp_scripts * * @uses GFForms::no_conflict_mode() */ public static function no_conflict_mode_script() { if ( ! get_option( 'gform_enable_noconflict' ) ) { return; } global $wp_scripts; $wp_required_scripts = array( 'admin-bar', 'common', 'jquery-color', 'utils', 'svg-painter' ); $gf_required_scripts = array( 'common' => array( 'gform_tooltip_init', 'sack' ), 'gf_edit_forms' => array( 'backbone', 'editor', 'gform_floatmenu', 'gform_forms', 'gform_form_admin', 'gform_form_editor', 'gform_gravityforms', 'gform_json', 'gform_menu', 'gform_placeholder', 'jquery-ui-autocomplete', 'jquery-ui-core', 'jquery-ui-datepicker', 'jquery-ui-sortable', 'jquery-ui-draggable', 'jquery-ui-droppable', 'jquery-ui-tabs', 'json2', 'media-editor', 'media-models', 'media-upload', 'media-views', 'plupload', 'plupload-flash', 'plupload-html4', 'plupload-html5', 'quicktags', 'rg_currency', 'thickbox', 'word-count', 'wp-plupload', 'wpdialogs-popup', 'wplink', 'wp-pointer', 'gform_chosen', ), 'gf_edit_forms_settings' => array( 'editor', 'word-count', 'quicktags', 'wpdialogs-popup', 'media-upload', 'wplink', 'backbone', 'jquery-ui-sortable', 'json2', 'media-editor', 'media-models', 'media-views', 'plupload', 'plupload-flash', 'plupload-html4', 'plupload-html5', 'plupload-silverlight', 'wp-plupload', 'gform_placeholder', 'gform_json', 'gform_gravityforms', 'gform_forms', 'gform_form_admin', 'jquery-ui-datepicker', 'gform_masked_input', 'sack', 'jquery-ui-autocomplete', 'wp-tinymce', 'wp-tinymce-root', 'wp-tinymce-lists', ), 'gf_new_form' => array( 'thickbox', 'jquery-ui-core', 'jquery-ui-sortable', 'jquery-ui-tabs', 'rg_currency', 'gform_gravityforms', 'gform_json', 'gform_form_admin', ), 'gf_entries' => array( 'thickbox', 'gform_gravityforms', 'wp-lists', 'gform_json', 'gform_field_filter', 'plupload-all', 'postbox', 'gform_chosen', ), 'gf_settings' => array(), 'gf_export' => array( 'gform_form_admin', 'jquery-ui-datepicker', 'gform_field_filter' ), 'gf_help' => array(), 'gf_system_status' => array( 'gform_system_report_clipboard', 'thickbox', 'gform_placeholder'), ); self::no_conflict_mode( $wp_scripts, $wp_required_scripts, $gf_required_scripts, 'scripts' ); } /** * Runs "no conflict mode". * * @since Unknown * @access private * * @used-by GFForms::no_conflict_mode_style() * @used-by GFForms::no_conflict_mode_script() * * @param WP_Scripts $wp_objects WP_Scripts object. * @param array $wp_required_objects Scripts required by WordPress Core. * @param array $gf_required_objects Scripts required by Gravity Forms. * @param string $type Determines if scripts or styles are being run through the function. */ private static function no_conflict_mode( &$wp_objects, $wp_required_objects, $gf_required_objects, $type = 'scripts' ) { $current_page = trim( strtolower( rgget( 'page' ) ) ); if ( empty( $current_page ) ) { $current_page = trim( strtolower( rgget( 'gf_page' ) ) ); } if ( empty( $current_page ) ) { $current_page = RG_CURRENT_PAGE; } $view = rgempty( 'view', $_GET ) ? 'default' : rgget( 'view' ); $page_objects = isset( $gf_required_objects[ $current_page . '_' . $view ] ) ? $gf_required_objects[ $current_page . '_' . $view ] : rgar( $gf_required_objects, $current_page ); //disable no-conflict if $page_objects is false if ( $page_objects === false ) { return; } if ( ! is_array( $page_objects ) ) { $page_objects = array(); } //merging wp scripts with gravity forms scripts $required_objects = array_merge( $wp_required_objects, $gf_required_objects['common'], $page_objects ); //allowing addons or other products to change the list of no conflict scripts $required_objects = apply_filters( "gform_noconflict_{$type}", $required_objects ); $queue = array(); foreach ( $wp_objects->queue as $object ) { if ( in_array( $object, $required_objects ) ) { $queue[] = $object; } } $wp_objects->queue = $queue; $required_objects = self::add_script_dependencies( $wp_objects->registered, $required_objects ); //unregistering scripts $registered = array(); foreach ( $wp_objects->registered as $script_name => $script_registration ) { if ( in_array( $script_name, $required_objects ) ) { $registered[ $script_name ] = $script_registration; } } $wp_objects->registered = $registered; } /** * Adds script dependencies needed. * * @since Unknown * @access private * * @used-by GFForms::no_conflict_mode() * * @param array $registered Registered scripts. * @param array $scripts Required scripts. * * @return array $scripts Scripts including dependencies. */ private static function add_script_dependencies( $registered, $scripts ) { //gets all dependent scripts linked to the $scripts array passed do { $dependents = array(); foreach ( $scripts as $script ) { $deps = isset( $registered[ $script ] ) && is_array( $registered[ $script ]->deps ) ? $registered[ $script ]->deps : array(); foreach ( $deps as $dep ) { if ( ! in_array( $dep, $scripts ) && ! in_array( $dep, $dependents ) ) { $dependents[] = $dep; } } } $scripts = array_merge( $scripts, $dependents ); } while ( ! empty( $dependents ) ); return $scripts; } /** * Integration with ManageWP. * * @since Unknown * @access public * * @param array $premium_update ManageWP update array. * * @return array $premium_update */ public static function premium_update_push( $premium_update ) { if ( ! function_exists( 'get_plugin_data' ) ) { include_once( ABSPATH . 'wp-admin/includes/plugin.php' ); } $update = GFCommon::get_version_info(); if ( rgar( $update, 'is_valid_key' ) == true && version_compare( GFCommon::$version, $update['version'], '<' ) ) { $gforms = get_plugin_data( __FILE__ ); $gforms['type'] = 'plugin'; $gforms['slug'] = 'gravityforms/gravityforms.php'; $gforms['new_version'] = ! rgempty( 'version', $update ) ? $update['version'] : false; $premium_update[] = $gforms; } return $premium_update; } /** * Integration with ManageWP. * * @since Unknown * @access public * * @param array $premium_update ManageWP update array. * * @return array $premium_update. */ public static function premium_update( $premium_update ) { if ( ! function_exists( 'get_plugin_data' ) ) { include_once( ABSPATH . 'wp-admin/includes/plugin.php' ); } $update = GFCommon::get_version_info(); if ( rgar( $update, 'is_valid_key' ) == true && version_compare( GFCommon::$version, $update['version'], '<' ) ) { $gforms = get_plugin_data( __FILE__ ); $gforms['slug'] = 'gravityforms/gravityforms.php'; // If not set by default, always pass theme template $gforms['type'] = 'plugin'; $gforms['url'] = ! rgempty( 'url', $update ) ? $update['url'] : false; // OR provide your own callback function for managing the update array_push( $premium_update, $gforms ); } return $premium_update; } /** * Validates that Gravity Forms is doing the database upgrade, and has permissions to do so. * * @since Unknown * @access public * * @param null $do_upgrade Not used. * @param string $hook_extra The plugin triggering the upgrade. * * @return bool|WP_Error True if successful. Otherwise WP_Error object. */ public static function validate_upgrade( $do_upgrade, $hook_extra ) { return gf_upgrade()->validate_upgrade( $do_upgrade, $hook_extra ); } // # PERMISSIONS --------------------------------------------------------------------------------------------------- /** * Determines if a user has a particular capability. * * @since Unknown * @access public * * @param array $all_caps All capabilities. * @param array $cap Required capability. Stored in the [0] key. * @param array $args Not used. * * @return array $all_caps All capabilities. */ public static function user_has_cap( $all_caps, $cap, $args ) { $gf_caps = GFCommon::all_caps(); $capability = rgar( $cap, 0 ); if ( $capability != 'gform_full_access' ) { return $all_caps; } if ( ! self::has_members_plugin() ) { //give full access to administrators if the members plugin is not installed if ( current_user_can( 'administrator' ) || ( is_multisite() && is_super_admin() ) ) { $all_caps['gform_full_access'] = true; } } elseif ( current_user_can( 'administrator' ) || ( is_multisite() && is_super_admin() ) ) { //checking if user has any GF permission. $has_gf_cap = false; foreach ( $gf_caps as $gf_cap ) { if ( rgar( $all_caps, $gf_cap ) ) { $has_gf_cap = true; } } if ( ! $has_gf_cap ) { //give full access to administrators if none of the GF permissions are active by the Members plugin $all_caps['gform_full_access'] = true; } } return $all_caps; } /** * Register the Gravity Forms capabilities group with the Members plugin. * * @since 2.4 * @access public */ public static function members_register_cap_group() { members_register_cap_group( 'gravityforms', array( 'label' => esc_html__( 'Gravity Forms', 'gravityforms' ), 'icon' => 'dashicons-gravityforms', 'caps' => array(), ) ); } /** * Register the capabilities and their human readable labels with the Members plugin. * * @since 2.4 * @access public */ public static function members_register_caps() { $caps = array( 'gravityforms_create_form' => esc_html__( 'Create Forms', 'gravityforms' ), 'gravityforms_delete_forms' => esc_html__( 'Delete Forms', 'gravityforms' ), 'gravityforms_edit_forms' => esc_html__( 'Edit Forms', 'gravityforms' ), 'gravityforms_preview_forms' => esc_html__( 'Preview Forms', 'gravityforms' ), 'gravityforms_view_entries' => esc_html__( 'View Entries', 'gravityforms' ), 'gravityforms_edit_entries' => esc_html__( 'Edit Entries', 'gravityforms' ), 'gravityforms_delete_entries' => esc_html__( 'Delete Entries', 'gravityforms' ), 'gravityforms_view_entry_notes' => esc_html__( 'View Entry Notes', 'gravityforms' ), 'gravityforms_edit_entry_notes' => esc_html__( 'Edit Entry Notes', 'gravityforms' ), 'gravityforms_export_entries' => esc_html__( 'Import/Export', 'gravityforms' ), 'gravityforms_view_settings' => esc_html__( 'View Plugin Settings', 'gravityforms' ), 'gravityforms_edit_settings' => esc_html__( 'Edit Plugin Settings', 'gravityforms' ), 'gravityforms_view_updates' => esc_html__( 'Manage Updates', 'gravityforms' ), 'gravityforms_view_addons' => esc_html__( 'Manage Add-Ons', 'gravityforms' ), 'gravityforms_system_status' => esc_html__( 'View System Status', 'gravityforms' ), 'gravityforms_uninstall' => esc_html__( 'Uninstall Gravity Forms', 'gravityforms' ), 'gravityforms_logging' => esc_html__( 'Logging Settings', 'gravityforms' ), 'gravityforms_api_settings' => esc_html__( 'REST API Settings', 'gravityforms' ), ); foreach ( $caps as $cap => $label ) { members_register_cap( $cap, array( 'label' => $label, 'group' => 'gravityforms', ) ); } } /** * Register Gravity Forms capabilities group with User Role Editor plugin. * * @since 2.4 * * @param array $groups Existing capabilities groups. * * @return array */ public static function filter_ure_capabilities_groups_tree( $groups = array() ) { $groups['gravityforms'] = array( 'caption' => esc_html__( 'Gravity Forms', 'gravityforms' ), 'parent' => 'custom', 'level' => 2, ); return $groups; } /** * Register Gravity Forms capabilities with Gravity Forms group in User Role Editor plugin. * * @since 2.4 * * @param array $groups Current capability groups. * @param string $cap_id Capability identifier. * * @return array */ public static function filter_ure_custom_capability_groups( $groups = array(), $cap_id = '' ) { // Get Gravity Forms capabilities. $caps = GFCommon::all_caps(); // If capability belongs to Gravity Forms, register it to group. if ( in_array( $cap_id, $caps, true ) ) { $groups[] = 'gravityforms'; } return $groups; } /** * Tests if the upload folder is writable and displays an error message if not. * * @since Unknown * @access public * * @return void */ public static function check_upload_folder() { // Check if upload folder is writable $folder = RGFormsModel::get_upload_root(); if ( empty( $folder ) ) { echo "
" . esc_html__( 'Upload folder is not writable. Export and file upload features will not be functional.', 'gravityforms' ) . '
'; } } /** * Checks if a Gravity Forms AJAX action is being performed. * * @since Unknown * @access public * * @return bool True if performing a Gravity Forms AJAX request. False, otherwise. */ public static function is_gravity_ajax_action() { //Gravity Forms AJAX requests $current_action = self::post( 'action' ); $gf_ajax_actions = array( 'rg_save_form', 'rg_change_input_type', 'rg_refresh_field_preview', 'rg_add_field', 'rg_duplicate_field', 'rg_delete_field', 'rg_select_export_form', 'rg_start_export', 'gf_upgrade_license', 'gf_delete_custom_choice', 'gf_save_custom_choice', 'gf_get_notification_post_categories', 'rg_update_lead_property', 'delete-gf_entry', 'rg_update_form_active', 'rg_update_notification_active', 'rg_update_confirmation_active', 'gf_resend_notifications', 'rg_dismiss_upgrade', 'gf_save_confirmation', 'gf_process_export', 'gf_download_export', 'gf_dismiss_message', 'gf_force_upgrade', ); if ( defined( 'DOING_AJAX' ) && DOING_AJAX && in_array( $current_action, $gf_ajax_actions ) ) { return true; } // Not a Gravity Forms ajax request. return false; } // Returns true if the current page is one of Gravity Forms pages. Returns false if not /** * Determines if the current page is part of Gravity Forms. * * @since Unknown * @access public * * @return bool */ public static function is_gravity_page() { // Gravity Forms pages $current_page = trim( strtolower( self::get( 'page' ) ) ); $gf_pages = array( 'gf_edit_forms', 'gf_new_form', 'gf_entries', 'gf_settings', 'gf_export', 'gf_help', 'gf_addons', 'gf_system_status' ); return in_array( $current_page, $gf_pages ); } /** * Creates the "Forms" left nav. * * WordPress generates the page hook suffix and screen ID by passing the translated menu title through sanitize_title(). * Screen options and metabox preferences are stored using the screen ID therefore: * 1. The page suffix or screen ID should never be hard-coded. Use get_current_screen()->id. * 2. The page suffix and screen ID must never change. * e.g. When an update for Gravity Forms is available an icon will be added to the the menu title. * The HTML for the icon will be stripped entirely by sanitize_title() because the number 1 is encoded. * * @since Unknown * @access public * * @return void */ public static function create_menu() { $has_full_access = current_user_can( 'gform_full_access' ); $min_cap = GFCommon::current_user_can_which( GFCommon::all_caps() ); if ( empty( $min_cap ) ) { $min_cap = 'gform_full_access'; } $addon_menus = array(); $addon_menus = apply_filters( 'gform_addon_navigation', $addon_menus ); $parent_menu = self::get_parent_menu( $addon_menus ); // Add a top-level left nav. $update_icon = GFCommon::has_update() && current_user_can( 'install_plugins' ) ? "1" : ''; $admin_icon = self::get_admin_icon_b64( GFForms::is_gravity_page() ? '#fff' : false ); $forms_hook_suffix = add_menu_page( __( 'Forms', 'gravityforms' ), __( 'Forms', 'gravityforms' ) . $update_icon, $has_full_access ? 'gform_full_access' : $min_cap, $parent_menu['name'], $parent_menu['callback'], $admin_icon, apply_filters( 'gform_menu_position', '16.9' ) ); add_action( 'load-' . $forms_hook_suffix, array( 'GFForms', 'load_screen_options' ) ); // Adding submenu pages add_submenu_page( $parent_menu['name'], __( 'Forms', 'gravityforms' ), __( 'Forms', 'gravityforms' ), $has_full_access ? 'gform_full_access' : 'gravityforms_edit_forms', 'gf_edit_forms', array( 'GFForms', 'forms' ) ); add_submenu_page( $parent_menu['name'], __( 'New Form', 'gravityforms' ), __( 'New Form', 'gravityforms' ), $has_full_access ? 'gform_full_access' : 'gravityforms_create_form', 'gf_new_form', array( 'GFForms', 'new_form' ) ); $entries_hook_suffix = add_submenu_page( $parent_menu['name'], __( 'Entries', 'gravityforms' ), __( 'Entries', 'gravityforms' ), $has_full_access ? 'gform_full_access' : 'gravityforms_view_entries', 'gf_entries', array( 'GFForms', 'all_leads_page' ) ); add_action( 'load-' . $entries_hook_suffix, array( 'GFForms', 'load_screen_options' ) ); if ( is_array( $addon_menus ) ) { foreach ( $addon_menus as $addon_menu ) { add_submenu_page( esc_html( $parent_menu['name'] ), esc_html( $addon_menu['label'] ), esc_html( $addon_menu['label'] ), $has_full_access ? 'gform_full_access' : $addon_menu['permission'], esc_html( $addon_menu['name'] ), $addon_menu['callback'] ); } } add_submenu_page( $parent_menu['name'], __( 'Settings', 'gravityforms' ), __( 'Settings', 'gravityforms' ), $has_full_access ? 'gform_full_access' : 'gravityforms_view_settings', 'gf_settings', array( 'GFForms', 'settings_page' ) ); add_submenu_page( $parent_menu['name'], __( 'Import/Export', 'gravityforms' ), __( 'Import/Export', 'gravityforms' ), $has_full_access ? 'gform_full_access' : ( current_user_can( 'gravityforms_export_entries' ) ? 'gravityforms_export_entries' : 'gravityforms_edit_forms' ), 'gf_export', array( 'GFForms', 'export_page' ) ); if ( current_user_can( 'install_plugins' ) ) { add_submenu_page( $parent_menu['name'], __( 'Add-Ons', 'gravityforms' ), __( 'Add-Ons', 'gravityforms' ), $has_full_access ? 'gform_full_access' : 'gravityforms_view_addons', 'gf_addons', array( 'GFForms', 'addons_page' ) ); } add_submenu_page( $parent_menu['name'], __( 'System Status', 'gravityforms' ), __( 'System Status', 'gravityforms' ), $has_full_access ? 'gform_full_access' : 'gravityforms_system_status', 'gf_system_status', array( 'GFForms', 'system_status' ) ); add_submenu_page( $parent_menu['name'], __( 'Help', 'gravityforms' ), __( 'Help', 'gravityforms' ), $has_full_access ? 'gform_full_access' : $min_cap, 'gf_help', array( 'GFForms', 'help_page' ) ); } /** * Gets the admin icon for the Forms menu item * * @since Unknown * @access public * * @param bool|string $color The hex color if changing the color of the icon. Defaults to false. * * @return string Base64 encoded icon string. */ public static function get_admin_icon_b64( $color = false ) { // Replace the hex color (default was #999999) to %s; it will be replaced by the passed $color if ( $color ) { $svg_xml = '' . self::get_admin_icon_svg( $color ); $icon = sprintf( 'data:image/svg+xml;base64,%s', base64_encode( sprintf( $svg_xml, $color ) ) ); } else { $svg_b64 = 'PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSItMTUgNzcgNTgxIDY0MCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAtMTUgNzcgNTgxIDY0MCIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PGcgaWQ9IkxheWVyXzIiPjxwYXRoIGZpbGw9IiM5OTk5OTkiIGQ9Ik00ODkuNSwyMjdMNDg5LjUsMjI3TDMxNS45LDEyNi44Yy0yMi4xLTEyLjgtNTguNC0xMi44LTgwLjUsMEw2MS44LDIyN2MtMjIuMSwxMi44LTQwLjMsNDQuMi00MC4zLDY5Ljd2MjAwLjVjMCwyNS42LDE4LjEsNTYuOSw0MC4zLDY5LjdsMTczLjYsMTAwLjJjMjIuMSwxMi44LDU4LjQsMTIuOCw4MC41LDBMNDg5LjUsNTY3YzIyLjItMTIuOCw0MC4zLTQ0LjIsNDAuMy02OS43VjI5Ni44QzUyOS44LDI3MS4yLDUxMS43LDIzOS44LDQ4OS41LDIyN3ogTTQwMSwzMDAuNHY1OS4zSDI0MXYtNTkuM0g0MDF6IE0xNjMuMyw0OTAuOWMtMTYuNCwwLTI5LjYtMTMuMy0yOS42LTI5LjZjMC0xNi40LDEzLjMtMjkuNiwyOS42LTI5LjZzMjkuNiwxMy4zLDI5LjYsMjkuNkMxOTIuOSw0NzcuNiwxNzkuNiw0OTAuOSwxNjMuMyw0OTAuOXogTTE2My4zLDM1OS43Yy0xNi40LDAtMjkuNi0xMy4zLTI5LjYtMjkuNnMxMy4zLTI5LjYsMjkuNi0yOS42czI5LjYsMTMuMywyOS42LDI5LjZTMTc5LjYsMzU5LjcsMTYzLjMsMzU5Ljd6IE0yNDEsNDkwLjl2LTU5LjNoMTYwdjU5LjNIMjQxeiIvPjwvZz48L3N2Zz4='; $icon = 'data:image/svg+xml;base64,' . $svg_b64; } return $icon; } /** * Returns the admin icon in SVG format. * * @since Unknown * @access public * * @param string $color The hex color if changing the color of the icon. Defaults to #999999. * * @return string */ public static function get_admin_icon_svg( $color = '#999999' ) { $svg = ''; return sprintf( $svg, $color ); } /** * Returns the parent menu item. * * It needs to be the same as the first sub-menu (otherwise WP will duplicate the main menu as a sub-menu). * * @since Unknown * @access public * * @param array $addon_menus Contains the add-on menu items. * * @return array $parent The parent menu array. */ public static function get_parent_menu( $addon_menus ) { if ( GFCommon::current_user_can_any( 'gravityforms_edit_forms' ) ) { $parent = array( 'name' => 'gf_edit_forms', 'callback' => array( 'GFForms', 'forms' ) ); } else if ( GFCommon::current_user_can_any( 'gravityforms_create_form' ) ) { $parent = array( 'name' => 'gf_new_form', 'callback' => array( 'GFForms', 'new_form' ) ); } else if ( GFCommon::current_user_can_any( 'gravityforms_view_entries' ) ) { $parent = array( 'name' => 'gf_entries', 'callback' => array( 'GFForms', 'all_leads_page' ) ); } else if ( is_array( $addon_menus ) && sizeof( $addon_menus ) > 0 ) { foreach ( $addon_menus as $addon_menu ) { if ( GFCommon::current_user_can_any( $addon_menu['permission'] ) ) { $parent = array( 'name' => $addon_menu['name'], 'callback' => $addon_menu['callback'] ); break; } } } else if ( GFCommon::current_user_can_any( 'gravityforms_view_settings' ) ) { $parent = array( 'name' => 'gf_settings', 'callback' => array( 'GFForms', 'settings_page' ) ); } else if ( GFCommon::current_user_can_any( 'gravityforms_export_entries' ) ) { $parent = array( 'name' => 'gf_export', 'callback' => array( 'GFForms', 'export_page' ) ); } else if ( GFCommon::current_user_can_any( 'gravityforms_view_addons' ) ) { $parent = array( 'name' => 'gf_addons', 'callback' => array( 'GFForms', 'addons_page' ) ); } else if ( GFCommon::current_user_can_any( 'gravityforms_system_status' ) ) { $parent = array( 'name' => 'gf_system_status', 'callback' => array( 'GFForms', 'system_status_page' ) ); } else if ( GFCommon::current_user_can_any( GFCommon::all_caps() ) ) { $parent = array( 'name' => 'gf_help', 'callback' => array( 'GFForms', 'help_page' ) ); } return $parent; } /** * Modifies the page title when on Gravity Forms settings pages. * * @since Unknown * @access public * * @param string $admin_title The current admin title * @param string $title Not used. * * @return string The modified admin title. */ public static function modify_admin_title( $admin_title, $title ) { $subview = rgget( 'subview' ); $form_id = rgget( 'id' ); if ( ! $form_id || rgget( 'page' ) != 'gf_edit_forms' || rgget( 'view' ) != 'settings' ) { return $admin_title; } require_once( GFCommon::get_base_path() . '/form_settings.php' ); $setting_tabs = GFFormSettings::get_tabs( $form_id ); $page_title = ''; foreach ( $setting_tabs as $tab ) { if ( $tab['name'] == $subview ) { $page_title = $tab['label']; } } if ( $page_title ) { $admin_title = sprintf( __( '%1$s ‹ %2$s — WordPress', 'gravityforms' ), esc_html( $page_title ), $admin_title ); } return $admin_title; } /** * Parses Gravity Forms shortcode attributes and displays the form. * * @since Unknown * @access public * * @param array $attributes The shortcode attributes. * @param null $content Defines the content of the shortcode. Defaults to null. * * @return mixed|string|void */ public static function parse_shortcode( $attributes, $content = null ) { /** * @var string $title * @var string $description * @var int $id * @var string $name * @var string $field_values * @var string $ajax * @var int $tabindex * @var string $action */ extract( shortcode_atts( array( 'title' => true, 'description' => true, 'id' => 0, 'name' => '', 'field_values' => '', 'ajax' => false, 'tabindex' => 0, 'action' => 'form', ), $attributes, 'gravityforms' ) ); $shortcode_string = ''; switch ( $action ) { case 'conditional': $shortcode_string = GFCommon::conditional_shortcode( $attributes, $content ); break; default: // don't retrieve form markup for custom actions if ( $action && $action != 'form' ) { break; } //displaying form $title = strtolower( $title ) == 'false' ? false : true; $description = strtolower( $description ) == 'false' ? false : true; $field_values = htmlspecialchars_decode( $field_values ); $field_values = str_replace( array( '&', '[', ']' ), array( '&', '[', ']' ), $field_values ); $ajax = strtolower( $ajax ) == 'true' ? true : false; //using name to lookup form if id is not specified if ( empty( $id ) ) { $id = $name; } parse_str( $field_values, $field_value_array ); //parsing query string like string for field values and placing them into an associative array $field_value_array = stripslashes_deep( $field_value_array ); $shortcode_string = self::get_form( $id, $title, $description, false, $field_value_array, $ajax, $tabindex ); } /** * Filters the shortcode. * * @since Unknown * * @param string $shortcode_string The full shortcode string. * @param array $attributes The attributes within the shortcode. * @param string $content The content of the shortcode, if available. */ $shortcode_string = apply_filters( "gform_shortcode_{$action}", $shortcode_string, $attributes, $content ); return $shortcode_string; } /** * Includes the add-on framework. * * @since Unknown * @access public */ public static function include_addon_framework() { require_once( GFCommon::get_base_path() . '/includes/addon/class-gf-addon.php' ); } /** * Includes the feed class for the add-on framework. * * @since Unknown * @access public */ public static function include_feed_addon_framework() { require_once( GFCommon::get_base_path() . '/includes/addon/class-gf-feed-addon.php' ); } /** * Includes the payment class for te add-on framework. * * @since Unknown * @access public */ public static function include_payment_addon_framework() { require_once( GFCommon::get_base_path() . '/includes/addon/class-gf-payment-addon.php' ); } /** * Includes the Gravity API * * @since Unknown * @access public */ public static function include_gravity_api() { require_once( GFCommon::get_base_path() . '/includes/class-gravity-api.php' ); } //------------------------------------------------- //----------- AJAX -------------------------------- /** * Triggers parsing of AJAX requests and outputs the response. * * @since Unknown * @access public * * @param null $wp Not used. */ public static function ajax_parse_request( $wp ) { if ( isset( $_POST['gform_ajax'] ) ) { die( self::get_ajax_form_response() ); } } /** * Parses the ajax submission and returns the response. * * @since 2.4.18 * * @return mixed|string|void|WP_Error */ public static function get_ajax_form_response() { parse_str( rgpost( 'gform_ajax' ), $args ); $form_id = isset( $args['form_id'] ) ? absint( $args['form_id'] ) : 0; require_once( GFCommon::get_base_path() . '/form_display.php' ); if ( GFFormDisplay::is_submit_form_id_valid( $form_id ) ) { $display_title = ! isset( $args['title'] ) || ! empty( $args['title'] ) ? true : false; $display_description = ! isset( $args['description'] ) || ! empty( $args['description'] ) ? true : false; $tabindex = isset( $args['tabindex'] ) ? absint( $args['tabindex'] ) : 0; parse_str( rgpost( 'gform_field_values' ), $field_values ); $result = GFFormDisplay::get_form( $form_id, $display_title, $display_description, false, $field_values, true, $tabindex ); } else { // The form ID in the footer inputs has been tampered with; handling it like a honeypot failure and returning the default confirmation instead. $default_confirmation = GFFormsModel::get_default_confirmation(); $result = GFFormDisplay::get_ajax_postback_html( $default_confirmation['message'] ); } return $result; } //------------------------------------------------------ //------------- PAGE/POST EDIT PAGE --------------------- /** * Determines if the "Add Form" button should be added to the page. * * @since Unknown * @access public * * @return boolean $display_add_form_button True if the page is supported. False otherwise. */ public static function page_supports_add_form_button() { $is_post_edit_page = in_array( RG_CURRENT_PAGE, array( 'post.php', 'page.php', 'page-new.php', 'post-new.php', 'customize.php', ) ); $display_add_form_button = apply_filters( 'gform_display_add_form_button', $is_post_edit_page ); return $display_add_form_button; } /** * Creates the "Add Form" button. * * @since Unknown * @access public */ public static function add_form_button() { $is_add_form_page = self::page_supports_add_form_button(); if ( ! $is_add_form_page ) { return; } // display button matching new UI echo '

' . esc_html__( 'Add Form', 'gravityforms' ) . '
'; } /** * Displays the popup to insert a form to a post/page. * * @since Unknown * @access public */ public static function add_mce_popup() { ?> ' . esc_html__( 'Settings', 'gravityforms' ) . '' ); return $links; } /** * Displays messages for the Gravity Forms listing on the Plugins page. * * Displays if the key is invalid or an update is available. * * @since Unknown * @since 2.4.15 Update to improve multisite updates. * @access public * * @param string $plugin_name The plugin filename. Immediately overwritten. * @param array $plugin_data An array of plugin data. */ public static function plugin_row( $plugin_name, $plugin_data ) { self::maybe_display_update_notification( $plugin_name, $plugin_data ); $add_ons = gf_upgrade()->get_min_addon_requirements(); if ( isset( $add_ons[ $plugin_name ] ) ) { $plugin_path = WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . $plugin_name; if ( ! file_exists( $plugin_path ) ) { return; } $plugin_data = get_plugin_data( $plugin_path, false, false ); $current_version = $plugin_data['Version']; $add_on = $add_ons[ $plugin_name ]; $min_version = $add_on['min_version']; if ( version_compare( $current_version, $min_version, '<' ) ) { $name = $add_on['name']; /* translators: 1: The name of the add-on, 2: version number. */ $message = esc_html__( 'This version of the %1$s is not compatible with the version of Gravity Forms that is installed. Upgrade this add-on to version %2$s or greater to avoid compatibility issues and potential loss of data.', 'gravityforms' ); echo '
' . sprintf( $message, $name, $min_version ) . '
'; } } } /** * Display Gravity Forms and add-ons update notifications if needed. * * @since 2.4.15 * * @param string $plugin_name The plugin filename. Immediately overwritten. * @param array $plugin_data An array of plugin data. * @param string $slug The add-on slug. * @param string $version The add-on version. */ public static function maybe_display_update_notification( $plugin_name, $plugin_data, $slug = '', $version = '' ) { if ( empty( $slug ) && $plugin_name !== 'gravityforms/gravityforms.php' ) { return; } if ( empty( $slug ) ) { $version_info = GFCommon::get_version_info(); $slug = 'gravityforms'; $version = GFCommon::$version; } else { $version_info = rgars( GFCommon::get_version_info(), 'offerings/' . $slug ); } $valid_key = rgar( GFCommon::get_version_info(), 'is_valid_key' ); $message = ''; // Display the message only for a multisite network. A single site install doesn't need it (WP handles it). if ( ( is_multisite() && ! is_network_admin() ) && version_compare( $version, rgar( $version_info, 'version' ), '<' ) ) { $changelog_url = wp_nonce_url( self_admin_url( 'admin-ajax.php?action=gf_get_changelog&plugin=' . $slug . '&TB_iframe=true&width=640&height=808' ) ); if ( ! current_user_can( 'update_plugins' ) || ! $valid_key ) { $message .= sprintf( /* translators: 1: plugin name, 2: open tag, 3: version number, 4: close tag */ esc_html__( 'There is a new version of %1$s available. %2$sView version %3$s details%4$s. ', 'gravityforms' ), $plugin_data['Name'], sprintf( /* translators: 1: plugin name, 2: version number, 3: changelog URL */ __( '', 'gravityforms' ), $plugin_data['Name'], $version_info['version'], $changelog_url ), $version_info['version'], '' ); } else { $upgrade_url = wp_nonce_url( self_admin_url( 'update.php?action=upgrade-plugin&plugin=' . urlencode( $plugin_name ) ), 'upgrade-plugin_' . $plugin_name ); $message .= sprintf( /* translators: 1: plugin name, 2: open tag, 3: version number, 4: close tag, 5: open tag 6. close tag */ esc_html__( 'There is a new version of %1$s available. %2$sView version %3$s details%4$s or %5$supdate now%6$s. ', 'gravityforms' ), $plugin_data['Name'], sprintf( /* translators: 1: plugin name, 2: version number, 3: changelog URL */ __( '', 'gravityforms' ), $plugin_data['Name'], $version_info['version'], $changelog_url ), $version_info['version'], '', sprintf( /* translators: 1: upgrade URL, 2: plugin name */ __( '', 'gravityforms' ), $upgrade_url, $plugin_data['Name'] ), '' ); } } if ( ! $valid_key ) { $message .= sprintf( esc_html__( '%sRegister%s your copy of Gravity Forms to receive access to automatic upgrades and support. Need a license key? %sPurchase one now%s.', 'gravityforms' ), '', '', '', '' ); } if ( ! empty( $message ) ) { if ( is_network_admin() ) { $active_class = is_plugin_active_for_network( $plugin_name ) ? ' active' : ''; } else { $active_class = is_plugin_active( $plugin_name ) ? ' active' : ''; } echo ''; echo ''; echo '
'; echo '

'; echo $message; echo '

'; // Apply the class "update" to the plugin row to get rid of the ugly border. echo " "; } } /** * Hooks into in_plugin_update_message-gravityforms/gravityforms.php and displays an update message specifically for Gravity Forms 2.3. * * @param $args * @param $response */ public static function in_plugin_update_message( $args, $response ) { if ( empty( $args['update'] ) ) { return; } if ( version_compare( $args['new_version'], '2.3', '>=' ) && version_compare( GFForms::$version, '2.3', '<' ) ) { $message = esc_html__( 'IMPORTANT: As this is a major update, we strongly recommend creating a backup of your site before updating.', 'gravityforms' ); require_once( GFCommon::get_base_path() . '/includes/system-status/class-gf-update.php' ); $updates = GF_Update::available_updates(); $addons_requiring_updates = array(); foreach ( $updates as $update ) { if ( $update['slug'] == 'gravityforms' ) { continue; } $update_available = version_compare( $update['installed_version'], $update['latest_version'], '<' ); if ( $update_available ) { $addons_requiring_updates[] = $update['name'] . ' ' . $update['installed_version']; } } if ( count( $addons_requiring_updates ) > 0 ) { /* translators: %s: version number */ $message .= '
' . sprintf( esc_html__( "The versions of the following add-ons you're running haven't been tested with Gravity Forms %s. Please update them or confirm compatibility before updating Gravity Forms, or you may experience issues:", 'gravityforms' ), $args['new_version'] ); $message .= ' ' . join( ', ', $addons_requiring_updates ); } echo sprintf( '

%s

', $message ); } } /** * Displays current version details on Plugins page * * @since Unknown * @access public */ public static function display_changelog() { if ( $_REQUEST['plugin'] != 'gravityforms' ) { return; } $page_text = self::get_changelog(); echo $page_text; exit; } /** * Get changelog with admin-ajax.php in GFForms::maybe_display_update_notification(). * * @since 2.4.15 */ public static function ajax_display_changelog() { check_admin_referer(); GFForms::display_changelog(); } /** * Gets the changelog for the newest version * * @since Unknown * @access public * * @return string $page_text The changelog. Error message if there's an issue. */ public static function get_changelog() { $key = GFCommon::get_key(); $body = "key=$key"; $options = array( 'method' => 'POST', 'timeout' => 3, 'body' => $body ); $options['headers'] = array( 'Content-Type' => 'application/x-www-form-urlencoded; charset=' . get_option( 'blog_charset' ), 'Content-Length' => strlen( $body ), 'User-Agent' => 'WordPress/' . get_bloginfo( 'version' ), 'Referer' => get_bloginfo( 'url' ) ); $raw_response = GFCommon::post_to_manager( 'changelog.php', GFCommon::get_remote_request_params(), $options ); if ( is_wp_error( $raw_response ) || 200 != $raw_response['response']['code'] ) { $page_text = sprintf( esc_html__( 'Oops!! Something went wrong. %sPlease try again or %scontact us%s.', 'gravityforms' ), '
', "", '' ); } else { $page_text = $raw_response['body']; if ( substr( $page_text, 0, 10 ) != '' ) { $page_text = ''; } else { $page_text = '
' . $page_text . '
'; } } return stripslashes( $page_text ); } //------------------------------------------------------ //-------------- DASHBOARD PAGE ------------------------- /** * Registers the dashboard widget. * * @since Unknown * @access public */ public static function dashboard_setup() { /** * Changes the dashboard widget title * * @param string $dashboard_title The dashboard widget title. */ $dashboard_title = apply_filters( 'gform_dashboard_title', __( 'Forms', 'gravityforms' ) ); wp_add_dashboard_widget( 'rg_forms_dashboard', $dashboard_title, array( 'GFForms', 'dashboard' ) ); } /** * Displays the dashboard UI. * * @since Unknown * @access public */ public static function dashboard() { $forms = RGFormsModel::get_form_summary(); if ( sizeof( $forms ) > 0 ) { ?>
0 ? "class='form_title_unread' style='font-weight:bold;'" : '' ?> href="admin.php?page=gf_entries&view=entries&id="> 0 ? "class='form_entries_unread' style='font-weight:bold;'" : '' ?> href="admin.php?page=gf_entries&view=entries&filter=unread&id=" aria-label="">

', '' ); ?>
", '' ); ?>
admin_url( 'admin-ajax.php' ), 'enable_text' => __( 'Enable auto-updates', 'gravityforms' ), 'disable_text' => __( 'Disable auto-updates', 'gravityforms' ), ) ); } if ( self::page_supports_add_form_button() ) { wp_enqueue_script( 'gform_shortcode_ui' ); wp_enqueue_style( 'gform_shortcode_ui' ); wp_localize_script( 'gform_shortcode_ui', 'gfShortcodeUIData', array( 'shortcodes' => self::get_shortcodes(), 'previewNonce' => wp_create_nonce( 'gf-shortcode-ui-preview' ), /** * Allows the enabling (false) or disabling (true) of a shortcode preview of a form * * @param bool $preview_disabled Defaults to true. False to enable. */ 'previewDisabled' => apply_filters( 'gform_shortcode_preview_disabled', true ), 'strings' => array( 'pleaseSelectAForm' => wp_strip_all_tags( __( 'Please select a form.', 'gravityforms' ) ), 'errorLoadingPreview' => wp_strip_all_tags( __( 'Failed to load the preview for this form.', 'gravityforms' ) ), ) ) ); } if ( self::has_members_plugin() && rgget( 'page' ) === 'roles' ) { wp_enqueue_style( 'gform_dashicons' ); } if ( empty( $scripts ) ) { return; } foreach ( $scripts as $script ) { wp_enqueue_script( $script ); } GFCommon::localize_gform_gravityforms_multifile(); } /** * Gets current page name. * * @since Unknown * @access public * * @return bool|string Page name or false. * Page names: * * new_form * form_list * form_editor * form_settings * confirmation * notification_list * notification_new * notification_edit * entry_list * entry_detail * entry_detail_edit * settings * addons * export_entry * export_form * import_form * updates */ public static function get_page() { if ( rgget( 'page' ) == 'gf_new_form' ) { return 'new_form'; } if ( rgget( 'page' ) == 'gf_edit_forms' && ! rgget( 'id' ) ) { return 'form_list'; } if ( rgget( 'page' ) == 'gf_edit_forms' && ! rgget( 'view' ) ) { return 'form_editor'; } if ( rgget( 'page' ) == 'gf_edit_forms' && rgget( 'view' ) == 'settings' && ( ! rgget( 'subview' ) || rgget( 'subview' ) == 'settings' ) ) { return 'form_settings'; } if ( rgget( 'page' ) == 'gf_edit_forms' && rgget( 'view' ) == 'settings' && rgget( 'subview' ) == 'confirmation' ) { return 'confirmation'; } if ( rgget( 'page' ) == 'gf_edit_forms' && rgget( 'view' ) == 'settings' && rgget( 'subview' ) == 'notification' && rgget( 'nid' ) ) { return 'notification_edit'; } if ( rgget( 'page' ) == 'gf_edit_forms' && rgget( 'view' ) == 'settings' && rgget( 'subview' ) == 'notification' && isset( $_GET['nid'] ) ) { return 'notification_edit'; } if ( rgget( 'page' ) == 'gf_edit_forms' && rgget( 'view' ) == 'settings' && rgget( 'subview' ) == 'notification' ) { return 'notification_list'; } if ( rgget( 'page' ) == 'gf_edit_forms' && rgget( 'view' ) == 'settings' && rgget( 'subview' ) ) { return 'form_settings_' . rgget( 'subview' ); } if ( rgget( 'page' ) == 'gf_entries' && ( ! rgget( 'view' ) || rgget( 'view' ) == 'entries' ) ) { return 'entry_list'; } if ( rgget( 'page' ) == 'gf_entries' && rgget( 'view' ) == 'entry' && isset( $_POST['screen_mode'] ) && $_POST['screen_mode'] == 'edit' ) { return 'entry_detail_edit'; } if ( rgget( 'page' ) == 'gf_entries' && rgget( 'view' ) == 'entry' ) { return 'entry_detail'; } if ( rgget( 'page' ) == 'gf_settings' ) { return 'settings'; } if ( rgget( 'page' ) == 'gf_addons' ) { return 'addons'; } if ( rgget( 'page' ) == 'gf_export' && ( rgget( 'view' ) == 'export_entry' || ! isset( $_GET['view'] ) ) ) { return 'export_entry'; } if ( rgget( 'page' ) == 'gf_export' && rgget( 'view' ) == 'export_form' ) { return 'export_form'; } if ( rgget( 'page' ) == 'gf_export' && rgget( 'view' ) == 'import_form' ) { return 'import_form'; } if ( rgget( 'page' ) == 'gf_system_status' ) { return rgget( 'subview' ) === 'updates' ? 'updates' : 'system_status'; } if ( defined( 'DOING_AJAX' ) && DOING_AJAX && ( ( isset( $_POST['form_id'] ) && rgpost( 'action' ) === 'rg_select_export_form' ) || ( isset( $_POST['export_form'] ) && rgpost( 'action' ) === 'gf_process_export' ) ) ) { return 'export_entry_ajax'; } return false; } /** * Gets the form. * * @since Unknown * @access public * * @uses GFFormDisplay::get_form() * @uses GFCommon::get_base_path() */ public static function get_form( $form_id, $display_title = true, $display_description = true, $force_display = false, $field_values = null, $ajax = false, $tabindex = 0 ) { require_once( GFCommon::get_base_path() . '/form_display.php' ); return GFFormDisplay::get_form( $form_id, $display_title, $display_description, $force_display, $field_values, $ajax, $tabindex ); } /** * Runs when the Forms menu item is clicked. * * Checks to see if the installation wizard should be displayed instead. * * @since Unknown * @access public */ public static function new_form() { if ( self::maybe_display_wizard() ) { return; }; self::form_list_page(); } /** * Enqueues scripts * * @since Unknown * @access public * * @uses GFFormDisplay::enqueue_scripts() */ public static function enqueue_scripts() { require_once( GFCommon::get_base_path() . '/form_display.php' ); GFFormDisplay::enqueue_scripts(); } /** * Prints form scripts. * * @since Unknown * @access public * * @uses GFFormDisplay::print_form_scripts() */ public static function print_form_scripts( $form, $ajax ) { require_once( GFCommon::get_base_path() . '/form_display.php' ); GFFormDisplay::print_form_scripts( $form, $ajax ); } /** * Displays the Forms page * * Passes everything off to GFFormDetail::forms_page * * @since Unknown * @access public * * @uses GFFormDetail::forms_page() */ public static function forms_page( $form_id ) { require_once( GFCommon::get_base_path() . '/form_detail.php' ); GFFormDetail::forms_page( $form_id ); } /** * Runs the Gravity Forms settings page. * * Checks to see if the installation wizard should be displayed. * * @since Unknown * @access public * * @uses GFSettings::settings_page() */ public static function settings_page() { if ( self::maybe_display_wizard() ) { return; }; require_once( GFCommon::get_base_path() . '/settings.php' ); GFSettings::settings_page(); } /** * Runs the Gravity Forms system status page. * * @since 2.2 * @access public * * @uses GFSystemStatus::system_status_page() */ public static function system_status() { require_once( GFCommon::get_base_path() . '/includes/system-status/class-gf-system-status.php' ); require_once( GFCommon::get_base_path() . '/includes/system-status/class-gf-system-report.php' ); require_once( GFCommon::get_base_path() . '/includes/system-status/class-gf-update.php' ); GF_System_Status::system_status_page(); } /** * Adds pages to the Gravity Forms Settings page * * @since Unknown * @access public * * @used-by GFSettings::add_settings_page() */ public static function add_settings_page( $name, $handle = '', $icon_path = '' ) { require_once( GFCommon::get_base_path() . '/settings.php' ); GFSettings::add_settings_page( $name, $handle, $icon_path ); } /** * Displays the help page * * @since Unknown * @access public * * @uses GFHelp::help_page() */ public static function help_page() { require_once( GFCommon::get_base_path() . '/help.php' ); GFHelp::help_page(); } /** * Displays the Gravity Forms Export page * * @since Unknown * @access public * * @uses GFForms::maybe_display_wizard() * @uses GFExport::export_page() */ public static function export_page() { if ( self::maybe_display_wizard() ) { return; }; require_once( GFCommon::get_base_path() . '/export.php' ); GFExport::export_page(); } /** * Target for the wp_ajax_gf_process_export ajax action requested from the export entries page. * * @since 2.0.0 * @access public * * @uses GFCommon::get_base_path() * @uses GFExport::ajax_process_export() */ public static function ajax_process_export() { require_once( GFCommon::get_base_path() . '/export.php' ); GFExport::ajax_process_export(); } /** * Target for the wp_ajax_gf_download_export ajax action requested from the export entries page. * * @since 2.0.0 * @access public * * @uses GFCommon::get_base_path() * @uses GFExport::ajax_download_export() */ public static function ajax_download_export() { require_once( GFCommon::get_base_path() . '/export.php' ); GFExport::ajax_download_export(); } /** * Target for the wp_ajax_gf_dismiss_message ajax action requested from the Gravity Forms admin pages. * * @since 2.0.0 * @access public * * @uses GFCommon::dismiss_message() */ public static function ajax_dismiss_message() { check_admin_referer( 'gf_dismissible_nonce', 'nonce' ); $key = rgget( 'message_key' ); $key = sanitize_key( $key ); GFCommon::dismiss_message( $key ); } /** * Target for the wp_ajax_gf_disable_logging AJAX action requested from WordPress admin pages. * * @since 2.2.4.2 * @access public * * @uses GFCommon::get_base_path() * @uses GFSettings::disable_logging() */ public static function ajax_disable_logging() { // Verify nonce. check_admin_referer( 'gf_disable_logging_nonce', 'nonce' ); // Load Settings class. if ( ! class_exists( 'GFSettings' ) ) { require_once( GFCommon::get_base_path() . '/settings.php' ); } // Disable logging. $disabled = GFSettings::disable_logging(); if ( $disabled ) { wp_send_json_success( esc_html__( 'Logging disabled.', 'gravityforms' ) ); } else { wp_send_json_error( esc_html__( 'Unable to disable logging.', 'gravityforms' ) ); } } /** * Target for the wp_ajax_gf_force_upgrade ajax action requested from the System Status page. * * Outputs a JSON string with the status and then triggers the background upgrader usually handled byt the cron healthcheck. * * @since 2.3.0.4 */ public static function ajax_force_upgrade() { check_ajax_referer( 'gf_force_upgrade', 'nonce' ); $status_label = get_option( 'gform_upgrade_status' ); if ( empty( $status_label ) ) { $status = 'complete'; $status_label = __( 'Finished', 'gravityforms' ); $percent_complete = 100; } else { $status = 'in_progress'; require_once( GFCommon::get_base_path() . '/includes/system-status/class-gf-system-report.php' ); $percent_complete = GF_System_Report::get_upgrade_percent_complete(); } $response = json_encode( array( 'status' => $status, 'status_label' => $status_label, 'percent' => (string) $percent_complete, ) ); echo $response; ob_end_flush(); // Simuate the healthcheck cron. GFForms::$background_upgrader->handle_cron_healthcheck(); // The healthcheck task will terminate anyway but exit just in case. exit; } /** * Runs the add-ons page * * If the display wizard needs to be displayed, do that instead. * * @since Unknown * @access public */ public static function addons_page() { if ( self::maybe_display_wizard() ) { return; }; wp_print_styles( array( 'thickbox' ) ); $plugins = get_plugins(); $installed_plugins = array(); foreach ( $plugins as $key => $plugin ) { $is_active = is_plugin_active( $key ); $installed_plugin = array( 'plugin' => $key, 'name' => $plugin['Name'], 'is_active' => $is_active ); $installed_plugin['activation_url'] = $is_active ? '' : wp_nonce_url( "plugins.php?action=activate&plugin={$key}", "activate-plugin_{$key}" ); $installed_plugin['deactivation_url'] = ! $is_active ? '' : wp_nonce_url( "plugins.php?action=deactivate&plugin={$key}", "deactivate-plugin_{$key}" ); $installed_plugins[] = $installed_plugin; } $nonces = self::get_addon_nonces(); $body = array( 'plugins' => urlencode( serialize( $installed_plugins ) ), 'nonces' => urlencode( serialize( $nonces ) ), 'key' => GFCommon::get_key() ); $options = array( 'body' => $body, 'headers' => array( 'Referer' => get_bloginfo( 'url' ) ), 'timeout' => 15 ); $raw_response = GFCommon::post_to_manager( 'api.php', "op=plugin_browser&{$_SERVER['QUERY_STRING']}", $options ); if ( is_wp_error( $raw_response ) || $raw_response['response']['code'] != 200 ) { echo "
" . esc_html__( 'Add-On browser is currently unavailable. Please try again later.', 'gravityforms' ) . '
'; } else { echo GFCommon::get_remote_message(); echo $raw_response['body']; } } /** * Gets all add-on information. * * @since Unknown * @access public * * @param string $api The API URL. * @param string $action The action needed. Determines the view. * @param object $args Additional arguments sent to the API * * @return bool|object API object if successful. False if error. */ public static function get_addon_info( $api, $action, $args ) { if ( $action == 'plugin_information' && empty( $api ) && ( ! rgempty( 'rg', $_GET ) || $args->slug == 'gravityforms' ) ) { $key = GFCommon::get_key(); $raw_response = GFCommon::post_to_manager( 'api.php', "op=get_plugin&slug={$args->slug}&key={$key}", array() ); if ( is_wp_error( $raw_response ) || $raw_response['response']['code'] != 200 ) { return false; } $plugin = unserialize( $raw_response['body'] ); $api = new stdClass(); $api->name = $plugin['title']; $api->version = $plugin['version']; $api->download_link = $plugin['download_url']; $api->tested = '10.0'; } return $api; } /** * Creates nonces for add-on installation pages. * * @since Unknown * @access public * * @return array|bool $nonces The nonces if the API response is fine. Otherwise, false. */ public static function get_addon_nonces() { $raw_response = GFCommon::post_to_manager( 'api.php', 'op=get_plugins', array() ); if ( is_wp_error( $raw_response ) || $raw_response['response']['code'] != 200 ) { return false; } $addons = unserialize( $raw_response['body'] ); $nonces = array(); foreach ( $addons as $addon ) { $nonces[ $addon['key'] ] = wp_create_nonce( "install-plugin_{$addon['key']}" ); } return $nonces; } /** * Begins exports. * * @since Unknown * @access public * * @uses GFExport::start_export() */ public static function start_export() { require_once( GFCommon::get_base_path() . '/export.php' ); GFExport::start_export(); } /** * Gets the post categories. * * @since Unknown * @access public * * @uses GFFormDetail::get_post_category_values() */ public static function get_post_category_values() { require_once( GFCommon::get_base_path() . '/form_detail.php' ); GFFormDetail::get_post_category_values(); } /** * Gets and displays the rules for an address field, depending on the address type. * * @since Unknown * @access public */ public static function get_address_rule_values_select() { $address_type = rgpost( 'address_type' ); $value = rgpost( 'value' ); $id = sanitize_text_field( rgpost( 'id' ) ); $form_id = absint( rgpost( 'form_id' ) ); $address_field = new GF_Field_Address(); $address_types = $address_field->get_address_types( $form_id ); $markup = ''; $type_obj = $address_type && isset( $address_types[ $address_type ] ) ? $address_types[ $address_type ] : 'international'; switch ( $address_type ) { case 'international': $items = $address_field->get_countries(); break; default: $items = $type_obj['states']; } $markup = sprintf( '', esc_attr( $id ), $address_field->get_state_dropdown( $items, $value ) ); echo $markup; die(); } /** * Gets post categories for display in Notifications. * * @since Unknown * @access public * * @uses GFNotification::get_post_category_values() */ public static function get_notification_post_category_values() { require_once( GFCommon::get_base_path() . '/notification.php' ); GFNotification::get_post_category_values(); } /** * Fires off the entries page. * * Checks if the installation wizard is needed. If so, does that instead. * * @since Unknown * @access public * * @uses GFForms::maybe_display_wizard() * @uses GFEntryDetail::lead_detail_page() * @uses GFEntryList::all_entries_page() */ public static function all_leads_page() { if ( self::maybe_display_wizard() ) { return; }; $view = rgget( 'view' ); $lead_id = rgget( 'lid' ); if ( $view == 'entry' && ( rgget( 'lid' ) || ! rgblank( rgget( 'pos' ) ) ) ) { require_once( GFCommon::get_base_path() . '/entry_detail.php' ); GFEntryDetail::lead_detail_page(); } else if ( $view == 'entries' || empty( $view ) ) { require_once( GFCommon::get_base_path() . '/entry_list.php' ); GFEntryList::all_entries_page(); } else { $form_id = rgget( 'id' ); $form_id = absint( $form_id ); /** * Fires when viewing entries of a certain form * * @since Unknown * * @param string $view The current view/entry type * @param string $form_id The current form ID * @param string $lead_id The current entry ID */ do_action( 'gform_entries_view', $view, $form_id, $lead_id ); } } /** * Gets the Form List page. * * @since Unknown * @access public * * @uses GFFormList::form_list_page() */ public static function form_list_page() { require_once( GFCommon::get_base_path() . '/form_list.php' ); GFFormList::form_list_page(); } /** * Handles the view when accessing specific forms * * If needed, displays the installation wizard instead. * * @since Unknown * @access public * * @uses GFForms::maybe_display_wizard() * @uses GFCommon::ensure_wp_version() * @uses GFForms::get() * @uses GFEntryList::leads_page() * @uses GFEntryDetail::lead_detail_page() * @uses GFFormSettings::form_settings_page() * @uses GFForms::forms_page() * @uses GFForms::form_list_page() */ public static function forms() { if ( ! GFCommon::ensure_wp_version() ) { return; } if ( self::maybe_display_wizard() ) { return; }; $id = RGForms::get( 'id' ); $view = RGForms::get( 'view' ); if ( $view == 'entries' ) { require_once( GFCommon::get_base_path() . '/entry_list.php' ); GFEntryList::leads_page( $id ); } else if ( $view == 'entry' ) { require_once( GFCommon::get_base_path() . '/entry_detail.php' ); GFEntryDetail::lead_detail_page(); } else if ( $view == 'notification' ) { require_once( GFCommon::get_base_path() . '/notification.php' ); //GFNotification::notification_page($id); } else if ( $view == 'settings' ) { require_once( GFCommon::get_base_path() . '/form_settings.php' ); GFFormSettings::form_settings_page( $id ); } else if ( empty( $view ) ) { if ( is_numeric( $id ) ) { self::forms_page( $id ); } else { self::form_list_page(); } } /** * Fires an action based on the form view * * @since Unknown * * @param string $view The current view * @param string $id The form ID */ do_action( 'gform_view', $view, $id ); } /** * Obtains $_GET values or values from an array. * * @since Unknown * @access public * * @param string $name The ID of a specific value. * @param array $array An optional array to search through. Defaults to null. * * @return string The value. Empty if not found. */ public static function get( $name, $array = null ) { if ( ! isset( $array ) ) { $array = $_GET; } if ( isset( $array[ $name ] ) ) { return $array[ $name ]; } return ''; } /** * Obtains $_POST values. * * @since Unknown * @access public * * @param string $name The ID of the value to obtain * @param bool $do_stripslashes If stripslashes_deep should be run on the result. Defaults to true. * * @return string The value. Empty if not found. */ public static function post( $name, $do_stripslashes = true ) { if ( isset( $_POST[ $name ] ) ) { return $do_stripslashes ? stripslashes_deep( $_POST[ $name ] ) : $_POST[ $name ]; } return ''; } /** * Resends failed notifications * * @since Unknown * @access public * * @uses GFCommon::send_notification() */ public static function resend_notifications() { check_admin_referer( 'gf_resend_notifications', 'gf_resend_notifications' ); $form_id = absint( rgpost( 'formId' ) ); $leads = rgpost( 'leadIds' ); // may be a single ID or an array of IDs if ( 0 == $leads ) { // get all the lead ids for the current filter / search $filter = rgpost( 'filter' ); $search = rgpost( 'search' ); $star = $filter == 'star' ? 1 : null; $read = $filter == 'unread' ? 0 : null; $status = in_array( $filter, array( 'trash', 'spam' ) ) ? $filter : 'active'; $search_criteria['status'] = $status; if ( $star ) { $search_criteria['field_filters'][] = array( 'key' => 'is_starred', 'value' => (bool) $star ); } if ( ! is_null( $read ) ) { $search_criteria['field_filters'][] = array( 'key' => 'is_read', 'value' => (bool) $read ); } $search_field_id = rgpost( 'fieldId' ); if ( isset( $_POST['fieldId'] ) && $_POST['fieldId'] !== '' ) { $key = $search_field_id; $val = $search; $strpos_row_key = strpos( $search_field_id, '|' ); if ( $strpos_row_key !== false ) { //multi-row $key_array = explode( '|', $search_field_id ); $key = $key_array[0]; $val = $key_array[1] . ':' . $val; } $search_criteria['field_filters'][] = array( 'key' => $key, 'operator' => rgempty( 'operator', $_POST ) ? 'is' : rgpost( 'operator' ), 'value' => $val, ); } $leads = GFFormsModel::search_lead_ids( $form_id, $search_criteria ); } else { $leads = ! is_array( $leads ) ? array( $leads ) : $leads; } /** * Filters the notifications to be re-sent * * @since Unknown * * @param array $form_meta The Form Object * @param array $leads The entry IDs */ $form = gf_apply_filters( array( 'gform_before_resend_notifications', $form_id ), RGFormsModel::get_form_meta( $form_id ), $leads ); if ( empty( $leads ) || empty( $form ) ) { esc_html_e( 'There was an error while resending the notifications.', 'gravityforms' ); die(); }; $notifications = json_decode( rgpost( 'notifications' ) ); if ( ! is_array( $notifications ) ) { die( esc_html__( 'No notifications have been selected. Please select a notification to be sent.', 'gravityforms' ) ); } if ( ! rgempty( 'sendTo', $_POST ) && ! GFCommon::is_valid_email_list( rgpost( 'sendTo' ) ) ) { die( sprintf( esc_html__( 'The %sSend To%s email address provided is not valid.', 'gravityforms' ), '', '' ) ); } foreach ( $leads as $lead_id ) { $lead = RGFormsModel::get_lead( $lead_id ); foreach ( $notifications as $notification_id ) { $notification = $form['notifications'][ $notification_id ]; if ( ! $notification ) { continue; } //overriding To email if one was specified if ( rgpost( 'sendTo' ) ) { $notification['to'] = rgpost( 'sendTo' ); $notification['toType'] = 'email'; } /** * Allow the resend notification email to be skipped * * @since 2.3 * * @param bool $abort_email Should we prevent this email being sent? * @param array $notification The current notification object. * @param array $form The current form object. * @param array $lead The current entry object. */ $abort_email = apply_filters( 'gform_disable_resend_notification', false, $notification, $form, $lead ); if ( ! $abort_email ) { GFCommon::send_notification( $notification, $form, $lead ); } /** * Fires after the current notification processing is finished * * @since 2.3 * * @param array $notification The current notification object. * @param array $form The current form object. * @param array $lead The current entry object. */ do_action( 'gform_post_resend_notification', $notification, $form, $lead ); } } /** * Fires after the resend notifications processing is finished * * @since 2.3 * * @param array $form The current form object. * @param array $lead The current entry object. */ do_action( 'gform_post_resend_all_notifications', $form, $lead ); die(); } //------------------------------------------------- //----------- AJAX CALLS -------------------------- /** * Gets the CAPTCHA image for the form editor and displays it. * * Called via AJAX. * * @since Unknown * @access public */ public static function captcha_image() { $field_properties = array( 'type' => 'captcha', 'simpleCaptchaSize' => $_GET['size'], 'simpleCaptchaFontColor' => $_GET['fg'], 'simpleCaptchaBackgroundColor' => $_GET['bg'] ); /* @var GF_Field_CAPTCHA $field */ $field = GF_Fields::create( $field_properties ); if ( $_GET['type'] == 'math' ) { $captcha = $field->get_math_captcha( $_GET['pos'] ); } else { $captcha = $field->get_captcha(); } @ini_set( 'memory_limit', '256M' ); $image = imagecreatefrompng( $captcha['path'] ); include_once( ABSPATH . 'wp-admin/includes/image-edit.php' ); wp_stream_image( $image, 'image/png', 0 ); imagedestroy( $image ); die(); } /** * Updates the form status (active/inactive). * * Called via AJAX. * * @since Unknown * @access public * * @uses GFFormsModel::update_form_active() */ public static function update_form_active() { check_ajax_referer( 'rg_update_form_active', 'rg_update_form_active' ); if ( GFCommon::current_user_can_any( 'gravityforms_edit_forms' ) ) { GFFormsModel::update_form_active( $_POST['form_id'], $_POST['is_active'] ); } else { wp_die( -1, 403 ); } } /** * Updates the notification status (active/inactive). * * Called via AJAX. * * @since Unknown * @access public * * @uses GFFormsModel::update_notification_active() */ public static function update_notification_active() { check_ajax_referer( 'rg_update_notification_active', 'rg_update_notification_active' ); if ( GFCommon::current_user_can_any( 'gravityforms_edit_forms' ) ) { GFFormsModel::update_notification_active( $_POST['form_id'], $_POST['notification_id'], $_POST['is_active'] ); } else { wp_die( -1, 403 ); } } /** * Updates the confirmation status (active/inactive). * * Called via AJAX. * * @since Unknown * @access public * * @since GFFormsModel::update_confirmation_active() */ public static function update_confirmation_active() { check_ajax_referer( 'rg_update_confirmation_active', 'rg_update_confirmation_active' ); if ( GFCommon::current_user_can_any( 'gravityforms_edit_forms' ) ) { GFFormsModel::update_confirmation_active( $_POST['form_id'], $_POST['confirmation_id'], $_POST['is_active'] ); } else { wp_die( -1, 403 ); } } /** * Updates the entry properties. * * Called via AJAX. * * @since Unknown * @access public * * @uses GFFormsModel::update_entry_property() */ public static function update_lead_property() { check_ajax_referer( 'rg_update_lead_property', 'rg_update_lead_property' ); GFFormsModel::update_entry_property( $_POST['lead_id'], $_POST['name'], $_POST['value'] ); } /** * Updates the entry status. * * Called via AJAX. * * @since Unknown * @access public * * @uses GFFormsModel::update_lead_property() * @uses GFFormsModel::delete_lead() */ public static function update_lead_status() { check_ajax_referer( 'gf_delete_entry' ); $status = rgpost( 'status' ); $lead_id = rgpost( 'entry' ); $entry = GFAPI::get_entry( $lead_id ); $form = GFAPI::get_form( $entry['form_id'] ); switch ( $status ) { case 'unspam': GFFormsModel::update_entry_property( $lead_id, 'status', 'active' ); break; case 'restore': if ( GFCommon::current_user_can_any( 'gravityforms_delete_entries' ) ) { GFFormsModel::update_entry_property( $lead_id, 'status', 'active' ); } break; case 'delete': if ( GFCommon::current_user_can_any( 'gravityforms_delete_entries' ) ) { GFFormsModel::delete_entry( $lead_id ); } break; case 'trash': if ( GFCommon::current_user_can_any( 'gravityforms_delete_entries' ) ) { GFFormsModel::update_entry_property( $lead_id, 'status', 'trash' ); } break; default : GFFormsModel::update_entry_property( $lead_id, 'status', $status ); break; } require_once( 'entry_list.php' ); $filter_links = GFEntryList::get_filter_links( $form ); $counts = array(); foreach ( $filter_links as $filter_link ) { $id = $filter_link['id'] == '' ? 'all' : $filter_link['id']; $counts[ $id . '_count' ] = $filter_link['count']; } $x = new WP_Ajax_Response(); $x->add( array( 'what' => 'gf_entry', 'id' => $lead_id, 'supplemental' => $counts, ) ); $x->send(); } // Settings /** * Runs the license upgrade. * * Called via AJAX. * * @since Unknown * @access public * * @uses GFSettings::upgrade_license() */ public static function upgrade_license() { require_once( GFCommon::get_base_path() . '/settings.php' ); GFSettings::upgrade_license(); } // Form detail /** * Saves the form in the form editor. * * Called via AJAX. * * @since Unknown * @access public * * @uses GFFormDetail::save_form() */ public static function save_form() { require_once( GFCommon::get_base_path() . '/form_detail.php' ); GFFormDetail::save_form(); } /** * Adds fields in the form editor. * * Called via AJAX. * * @since Unknown * @access public * * @uses GFFormDetail::add_field() */ public static function add_field() { require_once( GFCommon::get_base_path() . '/form_detail.php' ); GFFormDetail::add_field(); } /** * Duplicates fields in the form editor. * * Called via AJAX. * * @since Unknown * @access public * * @uses GFFormDetail::duplicate_field() */ public static function duplicate_field() { require_once( GFCommon::get_base_path() . '/form_detail.php' ); GFFormDetail::duplicate_field(); } /** * Deletes fields in the form editor. * * Called via AJAX. * * @since Unknown * @access public * * @uses \GFFormDetail::delete_field() */ public static function delete_field() { require_once( GFCommon::get_base_path() . '/form_detail.php' ); GFFormDetail::delete_field(); } /** * Changes the input type in the form editor. * * Called via AJAX. * * @since Unknown * @access public * * @uses GFFormDetail::change_input_type() */ public static function change_input_type() { require_once( GFCommon::get_base_path() . '/form_detail.php' ); GFFormDetail::change_input_type(); } /** * Refreshes the field preview. * * Called via AJAX. * * @since Unknown * @access public * * @uses \GFFormDetail::refresh_field_preview */ public static function refresh_field_preview() { require_once( GFCommon::get_base_path() . '/form_detail.php' ); GFFormDetail::refresh_field_preview(); } /** * Deletes custom choices from radio/checkbox/select/etc fields. * * Called via AJAX. * * @since Unknown * @access public * * @uses GFFormDetail::delete_custom_choice() */ public static function delete_custom_choice() { require_once( GFCommon::get_base_path() . '/form_detail.php' ); GFFormDetail::delete_custom_choice(); } /** * Saves custom choices from radio/checkbox/select/etc fields. * * Called via AJAX. * * @since Unknown * @access public * * @uses GFFormDetail::save_custom_choice() */ public static function save_custom_choice() { require_once( GFCommon::get_base_path() . '/form_detail.php' ); GFFormDetail::save_custom_choice(); } /** * Deletes a file from the entry detail view. * * Called via AJAX. * * @since Unknown * @access public * * @uses GFFormsModel::delete_file() */ public static function delete_file() { check_ajax_referer( 'rg_delete_file', 'rg_delete_file' ); $lead_id = intval( $_POST['lead_id'] ); $field_id = intval( $_POST['field_id'] ); $file_index = intval( $_POST['file_index'] ); RGFormsModel::delete_file( $lead_id, $field_id, $file_index ); die( "EndDeleteFile($field_id, $file_index);" ); } /** * Gets the form export data. * * Called via AJAX. * * @since Unknown * @access public * * @uses GFFormsModel::get_form_meta() */ public static function select_export_form() { check_ajax_referer( 'rg_select_export_form', 'rg_select_export_form' ); $form_id = intval( $_POST['form_id'] ); $form = RGFormsModel::get_form_meta( $form_id ); /** * Filters through the Form Export Page * * @since Unknown * * @param int $form The Form Object of the form to export */ $form = gf_apply_filters( array( 'gform_form_export_page', $form_id ), $form ); $filter_settings = GFCommon::get_field_filter_settings( $form ); $filter_settings_json = json_encode( $filter_settings ); $fields = array(); $form = GFExport::add_default_export_fields( $form ); if ( is_array( $form['fields'] ) ) { /* @var GF_Field $field */ foreach ( $form['fields'] as $field ) { $inputs = $field->get_entry_inputs(); if ( is_array( $inputs ) ) { foreach ( $inputs as $input ) { $fields[] = array( $input['id'], GFCommon::get_label( $field, $input['id'] ) ); } } else if ( ! $field->displayOnly ) { $fields[] = array( $field->id, GFCommon::get_label( $field ) ); } } } $field_json = GFCommon::json_encode( $fields ); die( "EndSelectExportForm($field_json, $filter_settings_json);" ); } /** * Saves a form confirmation. * * Called via AJAX. * * @since Unknown * @access public * * @uses GFFormSettings::save_confirmation() */ // public static function save_confirmation() { // require_once( GFCommon::get_base_path() . '/form_settings.php' ); // GFFormSettings::save_confirmation(); // } /** * Saves the form title. * * Called via AJAX. * * @since 2.0.2.5 * @access public * * @uses GFFormSettings::save_form_title() */ public static function save_form_title() { require_once( GFCommon::get_base_path() . '/form_settings.php' ); GFFormSettings::save_form_title(); } /** * Deletes a form confirmation. * * Called via AJAX. * * @since Unknown * @access public * * @uses GFFormSettings::delete_confirmation() */ public static function delete_confirmation() { require_once( GFCommon::get_base_path() . '/form_settings.php' ); GFFormSettings::delete_confirmation(); } // Form list /** * Saves a new form. * * Called via AJAX. * * @since Unknown * @access public * * @uses GFFormList::save_new_form() */ public static function save_new_form() { require_once( GFCommon::get_base_path() . '/form_list.php' ); GFFormList::save_new_form(); } /** * Used to check that background tasks are working. * * @since 2.3 */ public static function check_background_tasks() { check_ajax_referer( 'gf_check_background_tasks', 'nonce' ); echo 'ok'; die(); } /** * Displays the edit title popup. * * @since Unknown * @access public * * @param array $form The Form Object. */ public static function edit_form_title( $form ) { //Only allow users with form edit permissions to edit forms if ( ! GFCommon::current_user_can_any( 'gravityforms_edit_forms' ) ) { return; } ?>
' />
array(), 'inactive' => array(), ); foreach ( $all_forms as $form ) { if ( '1' === $form->is_active ) { $forms['active'][] = $form; } else if ( '0' === $form->is_active ) { $forms['inactive'][] = $form; } } // Enqueuing Chosen script and styling. wp_enqueue_script( 'gform_chosen', false, array( 'jquery' ), GFCommon::$version, true ); wp_enqueue_style( 'gform_chosen' ); ?>
0 ? $forms[0]->id : '0' : rgget( 'id' ); ?>
$menu_item ) { $priorities[ $k ] = rgar( $menu_item, 'priority' ); } array_multisort( $priorities, SORT_DESC, $menu_items ); $keys = array_keys( $menu_items ); $last_key = array_pop( $keys ); // array_pop(array_keys($menu_items)) causes a Strict Standards warning in WP 3.6 on PHP 5.4 foreach ( $menu_items as $key => $menu_item ) { if ( is_array( $menu_item ) ) { if ( GFCommon::current_user_can_any( rgar( $menu_item, 'capabilities' ) ) ) { $sub_menu_str = ''; $count_sub_menu_items = 0; $sub_menu_items = rgar( $menu_item, 'sub_menu_items' ); if ( is_array( $sub_menu_items ) ) { foreach ( $sub_menu_items as $k => $val ) { if ( false === GFCommon::current_user_can_any( rgar( $sub_menu_items[ $k ], 'capabilities' ) ) ) { unset( $sub_menu_items[ $k ] ); } } $sub_menu_items = array_values( $sub_menu_items ); //reset numeric keys $count_sub_menu_items = count( $sub_menu_items ); } $menu_class = rgar( $menu_item, 'menu_class' ); if ( $count_sub_menu_items == 1 ) { $label = $compact ? rgar( $menu_item, 'label' ) : rgar( $sub_menu_items[0], 'label' ); $menu_item = $sub_menu_items[0]; } else { $label = rgar( $menu_item, 'label' ); $sub_menu_str = self::toolbar_sub_menu_items( $sub_menu_items, $compact ); } $link_class = esc_attr( rgar( $menu_item, 'link_class' ) ); $icon = rgar( $menu_item, 'icon' ); $url = esc_url( rgar( $menu_item, 'url' ) ); $aria_label = rgar( $menu_item, 'aria-label' ); $aria_label = ( ! empty( $aria_label ) ) ? "aria-label='" . esc_attr( $aria_label ) . "'" : ''; $onclick = esc_attr( rgar( $menu_item, 'onclick' ) ); $label = esc_html( $label ); $target = rgar( $menu_item, 'target' ); $link = "{$icon} {$label}" . $sub_menu_str; if ( $compact ) { if ( $key == 'delete' ) { /** * A filter to allow the modification of the HTML link to delete a form * * @since Unknown * * @param string $link The HTML "Delete Form" Link */ $link = apply_filters( 'gform_form_delete_link', $link ); } $divider = $key == $last_key ? '' : ' | '; if ( $count_sub_menu_items > 0 ) { $menu_class .= ' gf_form_action_has_submenu'; } $output .= '' . $link . $divider . ''; } else { $output .= "
  • {$link}
  • "; } } } elseif ( $compact ) { //for backwards compatibility <1.7: form actions only $divider = $key == $last_key ? '' : ' | '; $output .= '' . $menu_item . $divider . ''; } } return $output; } /** * Gets the menu items to be displayed within the toolbar. * * @since Unknown * @access public * * @used-by GFForms::top_toolbar() * @uses GFForms::toolbar_class() * * @param string $form_id The form ID. * @param bool $compact True if the compact label should be used. Defaults to false. * * @return array $menu_items The menu items to be displayed. */ public static function get_toolbar_menu_items( $form_id, $compact = false ) { $menu_items = array(); $is_mobile = wp_is_mobile(); $form_id = absint( $form_id ); // ---- Form Editor ---- $edit_capabilities = array( 'gravityforms_edit_forms' ); $menu_items['edit'] = array( 'label' => __( 'Edit', 'gravityforms' ), 'short_label' => esc_html__( 'Editor', 'gravityforms' ), 'icon' => '', 'url' => '?page=gf_edit_forms&id=' . $form_id, 'menu_class' => 'gf_form_toolbar_editor', 'link_class' => self::toolbar_class( 'editor' ), 'capabilities' => $edit_capabilities, 'priority' => 1000, ); // ---- Form Settings ---- $sub_menu_items = self::get_form_settings_sub_menu_items( $form_id ); $menu_items['settings'] = array( 'label' => __( 'Settings', 'gravityforms' ), 'icon' => '', 'aria-label' => __( 'Edit settings for this form', 'gravityforms' ), 'url' => $is_mobile ? '#' : '?page=gf_edit_forms&view=settings&id=' . $form_id, 'menu_class' => 'gf_form_toolbar_settings', 'link_class' => self::toolbar_class( 'settings' ), 'sub_menu_items' => $sub_menu_items, 'capabilities' => $edit_capabilities, 'priority' => 900, ); // ---- Entries ---- $entries_capabilities = array( 'gravityforms_view_entries', 'gravityforms_edit_entries', 'gravityforms_delete_entries' ); $menu_items['entries'] = array( 'label' => __( 'Entries', 'gravityforms' ), 'icon' => '', 'aria-label' => __( 'View entries generated by this form', 'gravityforms' ), 'url' => '?page=gf_entries&id=' . $form_id, 'menu_class' => 'gf_form_toolbar_entries', 'link_class' => self::toolbar_class( 'entries' ), 'capabilities' => $entries_capabilities, 'priority' => 800, ); // ---- Preview ---- $preview_capabilities = array( 'gravityforms_edit_forms', 'gravityforms_create_form', 'gravityforms_preview_forms' ); $menu_items['preview'] = array( 'label' => __( 'Preview', 'gravityforms' ), 'icon' => '', 'url' => trailingslashit( site_url() ) . '?gf_page=preview&id=' . $form_id, 'menu_class' => 'gf_form_toolbar_preview', 'link_class' => self::toolbar_class( 'preview' ), 'target' => '_blank', 'capabilities' => $preview_capabilities, 'priority' => 700, ); /* // ---- Duplicate ---- $duplicate_capabilities = array( 'gravityforms_edit_forms', 'gravityforms_create_form' ); $menu_items['duplicate'] = array( 'label' => __( 'Duplicate', 'gravityforms' ), 'icon' => '', 'title' => __( 'Duplicate this form', 'gravityforms' ), 'url' => wp_nonce_url( "?page=gf_edit_forms&action=duplicate&arg={$form_id}", "gf_duplicate_form_{$form_id}" ), 'menu_class' => 'gf_form_toolbar_duplicate', 'link_class' => self::toolbar_class( 'duplicate' ), 'capabilities' => $duplicate_capabilities, 'priority' => 600, ); //---- Trash ---- $trash_capabilities = array( 'gravityforms_delete_forms' ); $menu_items['trash'] = array( 'label' => __( 'Trash', 'gravityforms' ), 'icon' => '', 'title' => __( 'Trash this form', 'gravityforms' ), 'url' => wp_nonce_url( "?page=gf_edit_forms&action=trash&arg={$form_id}", "gf_delete_form_{$form_id}" ), 'menu_class' => 'gf_form_toolbar_trash', 'link_class' => self::toolbar_class( 'trash' ), 'capabilities' => $trash_capabilities, 'priority' => 500, ); */ return $menu_items; } /** * Builds the sub-menu items within the Gravity Forms toolbar. * * @since Unknown * @access public * * @used-by GFForms::format_toolbar_menu_items() * * @param array $menu_items The menu items to be built * @param bool $compact True if the compact label should be used. False otherwise. * * @return string $sub_menu_items_string The menu item HTML */ public static function toolbar_sub_menu_items( $menu_items, $compact = false ) { if ( empty( $menu_items ) ) { return ''; } $sub_menu_items_string = ''; foreach ( $menu_items as $menu_item ) { if ( GFCommon::current_user_can_any( rgar( $menu_item, 'capabilities' ) ) ) { $menu_class = esc_attr( rgar( $menu_item, 'menu_class' ) ); $link_class = esc_attr( rgar( $menu_item, 'link_class' ) ); $url = esc_url( rgar( $menu_item, 'url' ) ); $label = esc_html( rgar( $menu_item, 'label' ) ); $target = esc_attr( rgar( $menu_item, 'target' ) ); $sub_menu_items_string .= "
  • {$label}
  • "; } } if ( $compact ) { $sub_menu_items_string = '
      ' . $sub_menu_items_string . '
    '; } else { $sub_menu_items_string = '
      ' . $sub_menu_items_string . '
    '; } return $sub_menu_items_string; } /** * Gets the form settings sub-menu items. * * @since Unknown * @access public * * @used-by GFForms::get_toolbar_menu_items() * @uses GFFormSettings::get_tabs() * * @param string $form_id The form ID. * * @return array $sub_menu_items The sub-menu items. */ public static function get_form_settings_sub_menu_items( $form_id ) { require_once( GFCommon::get_base_path() . '/form_settings.php' ); $sub_menu_items = array(); $tabs = GFFormSettings::get_tabs( $form_id ); foreach ( $tabs as $tab ) { if ( $tab['name'] == 'settings' ) { $form_setting_menu_item['label'] = 'Settings'; } $sub_menu_items[] = array( 'url' => admin_url( "admin.php?page=gf_edit_forms&view=settings&subview={$tab['name']}&id={$form_id}" ), 'label' => $tab['label'], 'capabilities' => ( isset( $tab['capabilities'] ) ) ? $tab['capabilities'] : array( 'gravityforms_edit_forms' ), ); } return $sub_menu_items; } /** * Gets the CSS class to be used for the toolbar. * * @since Unknown * @access private * * @used-by GFForms::get_toolbar_menu_items() * * @param string $item The Gravity Forms view (current page). * * @return string The class name. Empty string if the view isn't found. */ private static function toolbar_class( $item ) { switch ( $item ) { case 'editor': if ( in_array( rgget( 'page' ), array( 'gf_edit_forms', 'gf_new_form' ) ) && rgempty( 'view', $_GET ) ) { return 'gf_toolbar_active'; } break; case 'settings': if ( rgget( 'view' ) == 'settings' ) { return 'gf_toolbar_active'; } break; case 'notifications' : if ( rgget( 'page' ) == 'gf_new_form' ) { return 'gf_toolbar_disabled'; } else if ( rgget( 'page' ) == 'gf_edit_forms' && rgget( 'view' ) == 'notification' ) { return 'gf_toolbar_active'; } break; case 'entries' : if ( rgget( 'page' ) == 'gf_new_form' ) { return 'gf_toolbar_disabled'; } else if ( rgget( 'page' ) == 'gf_entries' && rgempty( 'view', $_GET ) ) { return 'gf_toolbar_active'; } break; case 'preview' : if ( rgget( 'page' ) == 'gf_new_form' ) { return 'gf_toolbar_disabled'; } break; } return ''; } /** * Modifies the top WordPress toolbar to add Gravity Forms menu items. * * @since Unknown * @access public * @global $wp_admin_bar * * @used-by GFForms::init() */ public static function admin_bar() { /** * @var WP_Admin_Bar $wp_admin_bar */ global $wp_admin_bar; if ( GFCommon::current_user_can_any( 'gravityforms_create_form' ) ) { $wp_admin_bar->add_node( array( 'id' => 'gravityforms-new-form', 'parent' => 'new-content', 'title' => esc_attr__( 'Form', 'gravityforms' ), 'href' => admin_url( 'admin.php?page="gf_new_form' ), ) ); } if ( ! get_option( 'gform_enable_toolbar_menu' ) ) { return; } if ( ! GFCommon::current_user_can_any( array( 'gravityforms_edit_forms', 'gravityforms_create_form', 'gravityforms_preview_forms', 'gravityforms_view_entries' ) ) ) { // The current user can't use anything on the menu so bail. return; } $args = array( 'id' => 'gform-forms', 'title' => '
    ' . esc_html__( 'Forms', 'gravityforms' ) . '', 'href' => admin_url( 'admin.php?page=gf_edit_forms' ), ); $wp_admin_bar->add_node( $args ); $recent_form_ids = GFFormsModel::get_recent_forms(); if ( $recent_form_ids ) { $forms = GFFormsModel::get_form_meta_by_id( $recent_form_ids ); $wp_admin_bar->add_node( array( 'id' => 'gform-form-recent-forms', 'parent' => 'gform-forms', 'title' => esc_html__( 'Recent', 'gravityforms' ), 'group' => true, ) ); foreach ( $recent_form_ids as $recent_form_id ) { foreach ( $forms as $form ) { if ( $form['id'] == $recent_form_id ) { $wp_admin_bar->add_node( array( 'id' => 'gform-form-' . $recent_form_id, 'parent' => 'gform-form-recent-forms', 'title' => esc_html( $form['title'] ), 'href' => GFCommon::current_user_can_any( 'gravityforms_edit_forms' ) ? admin_url( 'admin.php?page=gf_edit_forms&id=' . $recent_form_id ) : '', ) ); if ( GFCommon::current_user_can_any( 'gravityforms_edit_forms' ) ) { $wp_admin_bar->add_node( array( 'id' => 'gform-form-' . $recent_form_id . '-edit', 'parent' => 'gform-form-' . $recent_form_id, 'title' => esc_html__( 'Edit', 'gravityforms' ), 'href' => admin_url( 'admin.php?page=gf_edit_forms&id=' . $recent_form_id ), ) ); } if ( GFCommon::current_user_can_any( 'gravityforms_view_entries' ) ) { $wp_admin_bar->add_node( array( 'id' => 'gform-form-' . $recent_form_id . '-entries', 'parent' => 'gform-form-' . $recent_form_id, 'title' => esc_html__( 'Entries', 'gravityforms' ), 'href' => admin_url( 'admin.php?page=gf_entries&id=' . $recent_form_id ), ) ); } if ( GFCommon::current_user_can_any( 'gravityforms_edit_forms' ) ) { $wp_admin_bar->add_node( array( 'id' => 'gform-form-' . $recent_form_id . '-settings', 'parent' => 'gform-form-' . $recent_form_id, 'title' => esc_html__( 'Settings', 'gravityforms' ), 'href' => admin_url( 'admin.php?page=gf_edit_forms&view=settings&subview=settings&id=' . $recent_form_id ), ) ); } if ( GFCommon::current_user_can_any( array( 'gravityforms_edit_forms', 'gravityforms_create_form', 'gravityforms_preview_forms' ) ) ) { $wp_admin_bar->add_node( array( 'id' => 'gform-form-' . $recent_form_id . '-preview', 'parent' => 'gform-form-' . $recent_form_id, 'title' => esc_html__( 'Preview', 'gravityforms' ), 'href' => trailingslashit( site_url() ) . '?gf_page=preview&id=' . $recent_form_id, ) ); } } } } } if ( GFCommon::current_user_can_any( 'gravityforms_edit_forms' ) ) { $wp_admin_bar->add_node( array( 'id' => 'gform-forms-view-all', 'parent' => 'gform-forms', 'title' => esc_attr__( 'All Forms', 'gravityforms' ), 'href' => admin_url( 'admin.php?page=gf_edit_forms' ), ) ); } if ( GFCommon::current_user_can_any( 'gravityforms_create_form' ) ) { $wp_admin_bar->add_node( array( 'id' => 'gform-forms-new-form', 'parent' => 'gform-forms', 'title' => esc_attr__( 'New Form', 'gravityforms' ), 'href' => admin_url( 'admin.php?page=gf_new_form' ), ) ); } } /** * Determines if automatic updating should be processed. * * @since Unknown * @access public * * @used-by WP_Automatic_Updater::should_update() * @uses GFForms::is_auto_update_disabled() * * @param bool $update Whether or not to update. * @param object $item The update offer object. * * @return bool True if update should be processed. False otherwise. */ public static function maybe_auto_update( $update, $item ) { if ( isset( $item->slug ) && $item->slug == 'gravityforms' ) { GFCommon::log_debug( 'GFForms::maybe_auto_update() - Starting auto-update for gravityforms.' ); $auto_update_disabled = self::is_auto_update_disabled(); GFCommon::log_debug( 'GFForms::maybe_auto_update() - $auto_update_disabled: ' . var_export( $auto_update_disabled, true ) ); if ( $auto_update_disabled || version_compare( GFForms::$version, $item->new_version, '=>' ) ) { GFCommon::log_debug( 'GFForms::maybe_auto_update() - Aborting update.' ); return false; } $current_major = implode( '.', array_slice( preg_split( '/[.-]/', GFForms::$version ), 0, 1 ) ); $new_major = implode( '.', array_slice( preg_split( '/[.-]/', $item->new_version ), 0, 1 ) ); $current_branch = implode( '.', array_slice( preg_split( '/[.-]/', GFForms::$version ), 0, 2 ) ); $new_branch = implode( '.', array_slice( preg_split( '/[.-]/', $item->new_version ), 0, 2 ) ); if ( $current_major == $new_major && $current_branch == $new_branch ) { GFCommon::log_debug( __METHOD__ . '() - OK to update.' ); return true; } else { GFCommon::log_debug( __METHOD__ . '() - Aborting update. Not on the same major version.' ); return false; } } return $update; } /** * Checks if automatic updates are disabled. * * @since Unknown * @access public * * @used-by GFForms::maybe_auto_update() * @used DISALLOW_FILE_MODS * @used WP_INSTALLING * @used AUTOMATIC_UPDATER_DISABLED * @used GFORM_DISABLE_AUTO_UPDATE * * @return bool True if auto update is disabled. False otherwise. */ public static function is_auto_update_disabled() { // Currently WordPress won't ask Gravity Forms to update if background updates are disabled. // Let's double check anyway. // WordPress background updates are disabled if you don't want file changes. if ( defined( 'DISALLOW_FILE_MODS' ) && DISALLOW_FILE_MODS ) { return true; } if ( defined( 'WP_INSTALLING' ) ) { return true; } $wp_updates_disabled = defined( 'AUTOMATIC_UPDATER_DISABLED' ) && AUTOMATIC_UPDATER_DISABLED; /** * Overrides the WordPress AUTOMATIC_UPDATER_DISABLED constant. * * @since Unknown * * @param bool $wp_updates_disabled True if disables. False otherwise. */ $wp_updates_disabled = apply_filters( 'automatic_updater_disabled', $wp_updates_disabled ); if ( $wp_updates_disabled ) { GFCommon::log_debug( __METHOD__ . '() - Background updates are disabled in WordPress.' ); return true; } // Now check Gravity Forms Background Update Settings $enabled = get_option( 'gform_enable_background_updates' ); GFCommon::log_debug( 'GFForms::is_auto_update_disabled() - $enabled: ' . var_export( $enabled, true ) ); /** * Filter to disable Gravity Forms Automatic updates * * @param bool $enabled Check if automatic updates are enabled, and then disable it */ $disabled = apply_filters( 'gform_disable_auto_update', ! $enabled ); GFCommon::log_debug( 'GFForms::is_auto_update_disabled() - $disabled: ' . var_export( $disabled, true ) ); if ( ! $disabled ) { $disabled = defined( 'GFORM_DISABLE_AUTO_UPDATE' ) && GFORM_DISABLE_AUTO_UPDATE; GFCommon::log_debug( 'GFForms::is_auto_update_disabled() - GFORM_DISABLE_AUTO_UPDATE: ' . var_export( $disabled, true ) ); } return $disabled; } /** * Filter the auto-update message on the plugins page. * * @since Unknown * * @param string $html HTML of the auto-update message. * @param string $plugin_file Plugin file. * @param array $plugin_data Plugin details. * * @return string|void */ public static function auto_update_message( $html, $plugin_file, $plugin_data ) { // Check if the plugin is Gravity Forms or an add-on. if ( ! self::is_gf_or_addon( $plugin_data['PluginURI'] ) ) { return $html; } $update = GFCommon::get_version_info(); $no_update_message = esc_html__( 'Auto-updates unavailable.', 'gravityforms' ); // If it's not GF core, only filter the message if the license is invalid. if ( 'gravityforms.php' !== substr( $plugin_file, strrpos( $plugin_file, '/' ) + 1 ) ) { if ( ! rgar( $update, 'is_valid_key' ) ) { return $no_update_message; } else { return $html; } } // We've gotten this far, so it must be GF core. if ( ! rgar( $update, 'is_valid_key' ) ) { return $no_update_message; } if ( rgar( $plugin_data, 'auto-update-forced' ) ) { // auto-updates are enabled, so clicking on this will disable them. $message = esc_html__( 'Disable auto-updates', 'gravityforms' ); $action = 'disable'; } else { // auto-updates are disabled, so clicking on this will enable them. $message = esc_html__( 'Enable auto-updates', 'gravityforms' ); $action = 'enable'; } $html = sprintf( '%s', esc_url( 'admin.php?page=gf_settings' ), $action . '-gf-updates', wp_create_nonce( 'gf-updates' ), $message ); return $html; } /** * Filter the auto-update message on the Site Health page. * * @since 2.4.20.2 * * @param string $auto_updates_string Text of auto-update message. * @param string $plugin_path Plugin path. * @param array $plugin Plugin details. * @param bool $enabled Whether auto-updates are enabled. * * @return string|void */ public static function auto_update_debug_message( $auto_updates_string, $plugin_path, $plugin, $enabled ) { // Check if the plugin is Gravity Forms or an add-on. if ( ! self::is_gf_or_addon( $plugin['PluginURI'] ) ) { return $auto_updates_string; } $update = GFCommon::get_version_info(); $no_update_message = __( 'Please register your copy of Gravity Forms to enable automatic updates.', 'gravityforms' ); // If it's not GF core, only filter the message if the license is invalid. if ( 'gravityforms.php' !== substr( $plugin_path, strrpos( $plugin_path, '/' ) + 1 ) ) { if ( ! rgar( $update, 'is_valid_key' ) ) { return $no_update_message; } else { return $auto_updates_string; } } // Filter the message for GF core. if ( rgar( $update, 'is_valid_key' ) ) { return $auto_updates_string; } else { return $no_update_message; } } /** * Enable or disable auto-updates. * * AJAX function to enable or disable auto-updates from the WordPress plugins page. * * @since 2.4.20.2 */ public static function update_auto_update_setting() { if ( ! wp_verify_nonce( $_POST['nonce'], 'gf-updates' ) ) { wp_send_json_error( __( 'Permissions error.', 'gravityforms' ) ); } $acceptable_tasks = array( 'enable-gf-updates', 'disable-gf-updates' ); if ( ! rgar( $_POST, 'task' ) || ! in_array( $_POST['task'], $acceptable_tasks ) ) { wp_send_json_error( __( 'Error processing request. Please refresh and try again.', 'gravityforms' ) ); } if ( 'enable-gf-updates' == $_POST['task'] ) { update_option( 'gform_enable_background_updates', true ); wp_send_json_success( 'success' ); } else { update_option( 'gform_enable_background_updates', false ); wp_send_json_success( 'success' ); } } /** * Check if a plugin is Gravity Forms or an offical add-on. * * @since 2.4.20.2 * * @param string $plugin_uri The URI of the plugin as found in the plugin header. * * @return bool */ public static function is_gf_or_addon( $plugin_uri ) { if ( strpos( $plugin_uri, 'gravityforms.com' ) ) { return true; } else { return false; } } public static function deprecate_add_on_methods() { if ( ( defined( 'DOING_AJAX' ) && DOING_AJAX ) || ( defined( 'DOING_CRON' ) && DOING_CRON ) || ( defined( 'WP_INSTALLING' ) && WP_INSTALLING ) ) { return; } $deprecated = GFAddOn::get_all_deprecated_protected_methods(); if ( ! empty( $deprecated ) ) { foreach ( $deprecated as $method ) { _deprecated_function( $method, '1.9', 'public access level' ); } } } /** * Shortcode UI */ /** * Output a shortcode. * * Called via AJAX. * Used for displaying the shortcode in the TinyMCE editor. * * @since Unknown * @access public * @global $post */ public static function handle_ajax_do_shortcode() { $shortcode = ! empty( $_POST['shortcode'] ) ? sanitize_text_field( stripslashes( $_POST['shortcode'] ) ) : null; $post_id = ! empty( $_POST['post_id'] ) ? intval( $_POST['post_id'] ) : null; if ( ! current_user_can( 'edit_post', $post_id ) || ! wp_verify_nonce( $_POST['nonce'], 'gf-shortcode-ui-preview' ) ) { echo esc_html__( 'Error', 'gravityforms' ); exit; } $form_id = ! empty( $_POST['form_id'] ) ? intval( $_POST['form_id'] ) : null; global $post; $post = get_post( $post_id ); setup_postdata( $post ); self::enqueue_form_scripts( $form_id, true ); wp_print_scripts(); wp_print_styles(); echo do_shortcode( $shortcode ); // Disable the elements on the form ?> id ) ] = $form->title; } $default_attrs = array( array( 'label' => __( 'Select a form below to add it to your post or page.', 'gravityforms' ), 'tooltip' => __( 'Select a form from the list to add it to your post or page.', 'gravityforms' ), 'attr' => 'id', 'type' => 'select', 'section' => 'required', 'description' => __( "Can't find your form? Make sure it is active.", 'gravityforms' ), 'options' => $forms_options, ), array( 'label' => __( 'Display form title', 'gravityforms' ), 'attr' => 'title', 'default' => 'true', 'section' => 'standard', 'type' => 'checkbox', 'tooltip' => __( 'Whether or not to display the form title.', 'gravityforms' ) ), array( 'label' => __( 'Display form description', 'gravityforms' ), 'attr' => 'description', 'default' => 'true', 'section' => 'standard', 'type' => 'checkbox', 'tooltip' => __( 'Whether or not to display the form description.', 'gravityforms' ) ), array( 'label' => __( 'Enable Ajax', 'gravityforms' ), 'attr' => 'ajax', 'section' => 'standard', 'type' => 'checkbox', 'tooltip' => __( 'Specify whether or not to use Ajax to submit the form.', 'gravityforms' ) ), array( 'label' => 'Tabindex', 'attr' => 'tabindex', 'type' => 'number', 'tooltip' => __( 'Specify the starting tab index for the fields of this form.', 'gravityforms' ) ), ); /** * Filters through the shortcode builder actions (ajax, tabindex, form title) for adding a new form to a post, page, etc. * * @since Unknown * * @param array() Array of additional shortcode builder actions. Empty by default. */ $add_on_actions = apply_filters( 'gform_shortcode_builder_actions', array() ); if ( ! empty( $add_on_actions ) ) { $action_options = array( '' => __( 'Select an action', 'gravityforms' ) ); foreach ( $add_on_actions as $add_on_action ) { foreach ( $add_on_action as $key => $array ) { $action_options[ $key ] = $array['label']; } } $default_attrs[] = array( 'label' => 'Action', 'attr' => 'action', 'type' => 'select', 'options' => $action_options, 'tooltip' => __( 'Select an action for this shortcode. Actions are added by some add-ons.', 'gravityforms' ) ); } $shortcode = array( 'shortcode_tag' => 'gravityform', 'action_tag' => '', 'label' => 'Gravity Forms', 'attrs' => $default_attrs, ); $shortcodes[] = $shortcode; if ( ! empty( $add_on_actions ) ) { foreach ( $add_on_actions as $add_on_action ) { foreach ( $add_on_action as $key => $array ) { $attrs = array_merge( $default_attrs, $array['attrs'] ); $shortcode = array( 'shortcode_tag' => 'gravityform', 'action_tag' => $key, 'label' => rgar( $array, 'label' ), 'attrs' => $attrs, ); } } $shortcodes[] = $shortcode; } return $shortcodes; } /** * Enqueues scripts needed to display the form. * * @since Unknown * @access public * * @used GFFormDisplay::enqueue_form_scripts() * @used GFAddOn::get_registered_addons() * * @param string $form_id The displayed form ID. * @param bool $is_ajax True if form uses AJAX. False otherwise. */ public static function enqueue_form_scripts( $form_id, $is_ajax = false ) { require_once( GFCommon::get_base_path() . '/form_display.php' ); $form = RGFormsModel::get_form_meta( $form_id ); GFFormDisplay::enqueue_form_scripts( $form, $is_ajax ); $addons = GFAddOn::get_registered_addons(); foreach ( $addons as $addon ) { $a = call_user_func( array( $addon, 'get_instance' ) ); $a->enqueue_scripts( $form, $is_ajax ); } } /** * Displays the installation wizard or upgrade wizard when appropriate. * * @since 2.2 * @access public * * @return bool Was a wizard displayed? */ public static function maybe_display_wizard() { return gf_upgrade()->maybe_display_wizard(); } /** * Display admin notice when logging is enabled. * * @since 2.4 * @access public */ public static function maybe_display_logging_notice() { $notice_disabled = defined( 'GF_LOGGING_DISABLE_NOTICE' ) && GF_LOGGING_DISABLE_NOTICE; $logging_enabled = get_option( 'gform_enable_logging', false ) || is_plugin_active( 'gravityformslogging/logging.php' ); // If logging is disabled, return. if ( $notice_disabled || ! $logging_enabled || ! GFCommon::current_user_can_any( 'gravityforms_edit_settings' ) ) { return; } // Prepare message. $message = sprintf( '

    %s

    %s

    ', sprintf( esc_html__( "Gravity Forms logging is currently enabled. Log files can contain sensitive information so ensure that logging is only enabled for as long as is required for troubleshooting. %sClick here to disable logging.%s", 'gravityforms' ), '', '' ), esc_html__( "If you're currently receiving support, do not disable logging until the issue is resolved.", 'gravityforms' ) ); // Prepare script. $script = ""; printf( '
    %s
    %s', wp_create_nonce( 'gf_disable_logging_nonce' ), $message, $script ); } /** * Sets the screen options for the entry list. * * @since 2.0 * @access public * * @used-by Filter: set-screen-option * * @param bool|int $status Screen option value. Not used. Defaults to false. * @param string $option The option to check. * @param int $value The number of rows to display per page. * * @return array $return The filtered data */ public static function set_screen_options( $status, $option, $value ) { $return = false; if ( $option == 'gform_entries_screen_options' ) { $return = array(); $return['default_filter'] = sanitize_key( rgpost( 'gform_default_filter' ) ); $return['per_page'] = sanitize_key( rgpost( 'gform_per_page' ) ); } elseif ( $option = 'gform_forms_per_page' ) { $return = $value; } return $return; } /** * Returns the markup for the screen options for the entry list. * * @since 2.0 * @access public * * @used-by Filter: screen_settings * @used GFEntryList::get_screen_options_markup() * * @param string $status The current screen settings * @param WP_Screen $args WP_Screen object * * @return string $return The filtered screen settings */ public static function show_screen_options( $status, $args ) { $return = $status; if ( self::get_page() == 'entry_list' ) { require_once( GFCommon::get_base_path() . '/entry_list.php' ); $return = GFEntryList::get_screen_options_markup( $status, $args ); } return $return; } /** * Loads the screen options for the entry detail page. * * @since 2.0 * @access public * * @used GFEntryDetail::add_meta_boxes() */ public static function load_screen_options() { $screen = get_current_screen(); if ( ! is_object( $screen ) ) { return; } $page = GFForms::get_page(); if ( $page == 'form_list' ) { $args = array( 'label' => __( 'Forms per page', 'gravityforms' ), 'default' => 20, 'option' => 'gform_forms_per_page', ); add_screen_option( 'per_page', $args ); } elseif ( in_array( $page, array( 'entry_detail', 'entry_detail_edit' ) ) ) { require_once( GFCommon::get_base_path() . '/entry_detail.php' ); GFEntryDetail::add_meta_boxes(); } } /** * Daily cron task. Target for the gravityforms_cron action. * * - Performs self-healing * - Adds empty index files * - Deletes unclaimed export files. * - Deleted old log files. * - Deletes orphaned entry rows from the lead table. * * @since 2.0.0 * @access public * * @used-by Action: gravityforms_cron * @used GFForms::add_security_files() * @used GFForms::delete_old_export_files() * @used GFForms::delete_old_log_files() * @used GFForms::do_self_healing() * @used GFForms::delete_orphaned_entries() */ public static function cron() { GFCommon::log_debug( __METHOD__ . '(): Starting cron.' ); self::add_security_files(); self::delete_old_export_files(); self::delete_old_log_files(); self::do_self_healing(); if ( ! get_option( 'gform_enable_logging' ) ) { gf_logging()->delete_log_files(); } require_once( 'includes/class-personal-data.php' ); GF_Personal_Data::cron_task(); GFCommon::log_debug( __METHOD__ . '(): Done.' ); } /** * Deletes all entry export files from the server that haven't been claimed within 24 hours. * * @since 2.0.0 * @access public */ public static function delete_old_export_files() { GFCommon::log_debug( __METHOD__ . '(): Starting.' ); $uploads_folder = RGFormsModel::get_upload_root(); if ( ! is_dir( $uploads_folder ) || is_link( $uploads_folder ) ) { GFCommon::log_debug( __METHOD__ . '(): No upload root - bailing.' ); return; } $export_folder = $uploads_folder . 'export'; if ( ! is_dir( $export_folder ) || is_link( $export_folder ) ) { GFCommon::log_debug( __METHOD__ . '(): No export root - bailing.' ); return; } GFCommon::log_debug( __METHOD__ . '(): Start deleting old export files' ); foreach ( GFCommon::glob( '*.csv', $export_folder . DIRECTORY_SEPARATOR ) as $filename ) { $timestamp = filemtime( $filename ); if ( $timestamp < time() - DAY_IN_SECONDS ) { // Delete files over a day old GFCommon::log_debug( __METHOD__ . '(): Proceeding to delete ' . $filename ); $success = unlink( $filename ); GFCommon::log_debug( __METHOD__ . '(): Delete successful: ' . ( $success ? 'yes' : 'no' ) ); } } } /** * Deletes any log files that are older than one month. * * @since 2.0.0 * @access public */ public static function delete_old_log_files() { GFCommon::log_debug( __METHOD__ . '(): Starting.' ); $uploads_folder = RGFormsModel::get_upload_root(); if ( ! is_dir( $uploads_folder ) || is_link( $uploads_folder ) ) { GFCommon::log_debug( __METHOD__ . '(): No upload root - bailing.' ); return; } $logs_folder = $uploads_folder . 'logs'; if ( ! is_dir( $logs_folder ) || is_link( $logs_folder ) ) { GFCommon::log_debug( __METHOD__ . '(): No logs folder - bailing.' ); return; } GFCommon::log_debug( __METHOD__ . '(): Start deleting old log files' ); foreach ( GFCommon::glob( '*.txt', $logs_folder . DIRECTORY_SEPARATOR ) as $filename ) { $timestamp = filemtime( $filename ); if ( $timestamp < time() - MONTH_IN_SECONDS ) { // Delete files over one month old GFCommon::log_debug( __METHOD__ . '(): Proceeding to delete ' . $filename ); $success = unlink( $filename ); GFCommon::log_debug( __METHOD__ . '(): Delete successful: ' . ( $success ? 'yes' : 'no' ) ); } } } /** * Deletes all rows in the lead table that don't have corresponding rows in the details table. * * @deprecated * @since 2.0.0 * @access public * @global $wpdb */ public static function delete_orphaned_entries() { _deprecated_function( __METHOD__, '2.4.17' ); global $wpdb; if ( version_compare( GFFormsModel::get_database_version(), '2.3-beta-1', '<' ) || GFFormsModel::has_batch_field_operations() ) { return; } GFCommon::log_debug( __METHOD__ . '(): Starting to delete orphaned entries' ); $entry_table = GFFormsModel::get_entry_table_name(); $entry_meta_table = GFFormsModel::get_entry_meta_table_name(); $sql = "DELETE FROM {$entry_table} WHERE id NOT IN( SELECT entry_id FROM {$entry_meta_table} )"; $result = $wpdb->query( $sql ); GFCommon::log_debug( __METHOD__ . '(): Delete result: ' . print_r( $result, true ) ); } /** * Hooked into the 'admin_head' action. * * Outputs the styles for the Forms Toolbar menu. * Outputs gf vars if required. * * @since 2.0.1.2 * @access public */ public static function load_admin_bar_styles() { if ( ! get_option( 'gform_enable_toolbar_menu' ) ) { return; } if ( ! GFCommon::current_user_can_any( array( 'gravityforms_edit_forms', 'gravityforms_create_form', 'gravityforms_preview_forms', 'gravityforms_view_entries' ) ) ) { // The current user can't use anything on the menu so bail. return; } ?> drop_index() instead */ public static function drop_index( $table, $index ) { _deprecated_function( 'This function has been deprecated. Use gf_upgrade()->drop_index() instead', '2.2', 'gf_upgrade()->drop_index()' ); gf_upgrade()->drop_index( $table, $index ); } /** * Fixes case for database queries. * * @deprecated 2.2 * * @since Unknown * @access public * * @param array $cqueries Queries to be fixed. * * @return array $queries Queries after processing. */ public static function dbdelta_fix_case( $cqueries ) { _deprecated_function( 'dbdelta_fix_case', '2.2', 'gf_upgrade()->dbdelta_fix_case()' ); return gf_upgrade()->dbdelta_fix_case( $cqueries ); } public static function setup( $force_setup = false ) { _deprecated_function( 'This function has been deprecated. Use gf_upgrade()->maybe_upgrade() or gf_upgrade()->upgrade() instead', '2.2', 'gf_upgrade()->upgrade() or gf_upgrade()->maybe_upgrade()' ); if ( $force_setup ) { $current_version = get_option( 'rg_form_version' ); gf_upgrade()->upgrade( $current_version, true ); } else { gf_upgrade()->maybe_upgrade(); } } public static function setup_database() { _deprecated_function( 'This function has been deprecated. Use gf_upgrade()->upgrade_schema()', '2.2', 'gf_upgrade()->upgrade_schema()' ); gf_upgrade()->upgrade_schema(); } /** * Creates an instance of GF_Background_Upgrader and stores it in GFForms::$background_upgrader * * @since 2.3 */ public static function init_background_upgrader() { if ( empty( self::$background_upgrader ) ) { require_once( plugin_dir_path( __FILE__ ) . 'includes/class-gf-background-upgrader.php' ); self::$background_upgrader = new GF_Background_Upgrader(); } } /** * Target for the WordPress 'query' filter. Triggers an PHP Notice if an outdated add-on or custom code attempts to * access tables that are not valid for this version of Gravity Forms. * * @since 2.3 * * @param $query * * @return string */ public static function filter_query( $query ) { global $wpdb; if ( preg_match( "/$wpdb->prefix(rg_lead_detail|rg_lead_meta|rg_lead_notes|rg_lead|rg_form_meta|rg_form_view|rg_form|rg_incomplete_submissions)/", $query, $matches ) ) { if ( version_compare( GFFormsModel::get_database_version(), '2.3-dev-1', '>' ) ) { $table_name = $matches[0]; $url = 'https://docs.gravityforms.com/database-storage-structure-reference/#changes-from-gravity-forms-2-2'; /* translators: 1: The table name 2: the URL with further details */ $message = esc_html__( 'An outdated add-on or custom code is attempting to access the %1$s table which is not valid in this version of Gravity Forms. Update your add-ons and custom code to prevent loss of form data. Further details: %2$s', 'gravityforms' ); $notice = sprintf( $message, $table_name, $url ); trigger_error( $notice ); } } return $query; } /** * Target for the admin_notices action. * * @since 2.3 * * Displays site-side dismissible notices. */ public static function action_admin_notices() { GFCommon::display_dismissible_message( false, 'site-wide' ); } /** * Registers the Gravity Forms data exporter. * * @since 2.4 * * @param array $exporters * * @return array */ public static function register_data_exporter( $exporters ) { $exporters['gravityforms'] = array( 'exporter_friendly_name' => __( 'Gravity Forms Exporter' ), 'callback' => array( 'GFForms', 'data_exporter' ), ); return $exporters; } /** * Registers the Gravity Forms data eraser. * * @since 2.4 * * @param array $erasers * * @return array */ public static function register_data_eraser( $erasers ) { $erasers['gravityforms'] = array( 'eraser_friendly_name' => __( 'Gravity Forms Eraser' ), 'callback' => array( 'GFForms', 'data_eraser' ), ); return $erasers; } /** * Callback for the WordPress data exporter. * * @since 2.4 * * @param string $email_address * @param int $page * * @return array */ public static function data_exporter( $email_address, $page = 1 ) { require_once( 'includes/class-personal-data.php' ); return GF_Personal_Data::data_exporter( $email_address, $page ); } /** * Callback for the WordPress data eraser. * * @since 2.4 * * @param string $email_address * @param int $page * * @return array */ public static function data_eraser( $email_address, $page = 1 ) { require_once( 'includes/class-personal-data.php' ); return GF_Personal_Data::data_eraser( $email_address, $page ); } } /** * Class RGForms * * @deprecated * Exists only for backwards compatibility. Used GFForms instead. */ class RGForms extends GFForms { } /** * Main Gravity Forms function call. * * Should be used to insert a Gravity Form from code. * * @param string $id The form ID * @param bool $display_title If the form title should be displayed in the form. Defaults to true. * @param bool $display_description If the form description should be displayed in the form. Defaults to true. * @param bool $display_inactive If the form should be displayed if marked as inactive. Defaults to false. * @param array|null $field_values Default field values. Defaults to null. * @param bool $ajax If submission should be processed via AJAX. Defaults to false. * @param int $tabindex Starting tabindex. Defaults to 0. * @param bool $echo If the field should be echoed. Defaults to true. * * @return string|void */ function gravity_form( $id, $display_title = true, $display_description = true, $display_inactive = false, $field_values = null, $ajax = false, $tabindex = 0, $echo = true ) { if ( ! $echo ) { return GFForms::get_form( $id, $display_title, $display_description, $display_inactive, $field_values, $ajax, $tabindex ); } echo GFForms::get_form( $id, $display_title, $display_description, $display_inactive, $field_values, $ajax, $tabindex ); } /** * @return GF_Upgrade */ function gf_upgrade() { require_once( GFCommon::get_base_path() . '/includes/class-gf-upgrade.php' ); return GF_Upgrade::get_instance(); } /** * Enqueues form scripts for the specified form. * * @uses GFForms::enqueue_form_scripts() * * @param string $form_id The form ID. * @param bool $is_ajax If the form is submitted via AJAX. Defaults to false. */ function gravity_form_enqueue_scripts( $form_id, $is_ajax = false ) { GFForms::enqueue_form_scripts( $form_id, $is_ajax ); } if ( ! function_exists( 'rgget' ) ) { /** * Helper function for getting values from query strings or arrays * * @param string $name The key * @param array $array The array to search through. If null, checks query strings. Defaults to null. * * @return string The value. If none found, empty string. */ function rgget( $name, $array = null ) { if ( ! isset( $array ) ) { $array = $_GET; } if ( ! is_array( $array ) ) { return ''; } if ( isset( $array[ $name ] ) ) { return $array[ $name ]; } return ''; } } if ( ! function_exists( 'rgpost' ) ) { /** * Helper function to obtain POST values. * * @param string $name The key * @param bool $do_stripslashes Optional. Performs stripslashes_deep. Defaults to true. * * @return string The value. If none found, empty string. */ function rgpost( $name, $do_stripslashes = true ) { if ( isset( $_POST[ $name ] ) ) { return $do_stripslashes ? stripslashes_deep( $_POST[ $name ] ) : $_POST[ $name ]; } return ''; } } if ( ! function_exists( 'rgar' ) ) { /** * Get a specific property of an array without needing to check if that property exists. * * Provide a default value if you want to return a specific value if the property is not set. * * @since Unknown * @access public * * @param array $array Array from which the property's value should be retrieved. * @param string $prop Name of the property to be retrieved. * @param string $default Optional. Value that should be returned if the property is not set or empty. Defaults to null. * * @return null|string|mixed The value */ function rgar( $array, $prop, $default = null ) { if ( ! is_array( $array ) && ! ( is_object( $array ) && $array instanceof ArrayAccess ) ) { return $default; } if ( isset( $array[ $prop ] ) ) { $value = $array[ $prop ]; } else { $value = ''; } return empty( $value ) && $default !== null ? $default : $value; } } if ( ! function_exists( 'rgars' ) ) { /** * Gets a specific property within a multidimensional array. * * @since Unknown * @access public * * @param array $array The array to search in. * @param string $name The name of the property to find. * @param string $default Optional. Value that should be returned if the property is not set or empty. Defaults to null. * * @return null|string|mixed The value */ function rgars( $array, $name, $default = null ) { if ( ! is_array( $array ) && ! ( is_object( $array ) && $array instanceof ArrayAccess ) ) { return $default; } $names = explode( '/', $name ); $val = $array; foreach ( $names as $current_name ) { $val = rgar( $val, $current_name, $default ); } return $val; } } if ( ! function_exists( 'rgempty' ) ) { /** * Determines if a value is empty. * * @since Unknown * @access public * * @param string $name The property name to check. * @param array $array Optional. An array to check through. Otherwise, checks for POST variables. * * @return bool True if empty. False otherwise. */ function rgempty( $name, $array = null ) { if ( is_array( $name ) ) { return empty( $name ); } if ( ! $array ) { $array = $_POST; } $val = rgar( $array, $name ); return empty( $val ); } } if ( ! function_exists( 'rgblank' ) ) { /** * Checks if the string is empty * * @since Unknown * @access public * * @param string $text The string to check. * * @return bool True if empty. False otherwise. */ function rgblank( $text ) { return empty( $text ) && ! is_array( $text ) && strval( $text ) != '0'; } } if ( ! function_exists( 'rgobj' ) ) { /** * Gets a property value from an object * * @since Unknown * @access public * * @param object $obj The object to check * @param string $name The property name to check for * * @return string The property value */ function rgobj( $obj, $name ) { if ( isset( $obj->$name ) ) { return $obj->$name; } return ''; } } if ( ! function_exists( 'rgexplode' ) ) { /** * Converts a delimiter separated string to an array. * * @since Unknown * @access public * * @param string $sep The delimiter between values * @param string $string The string to convert * @param int $count The expected number of items in the resulting array * * @return array $ary The exploded array */ function rgexplode( $sep, $string, $count ) { $ary = explode( $sep, $string ); while ( count( $ary ) < $count ) { $ary[] = ''; } return $ary; } } if ( ! function_exists( 'gf_apply_filters' ) ) { //function gf_apply_filters( $filter, $modifiers, $value ) { /** * Gravity Forms pre-processing for apply_filters * * Allows additional filters based on form and field ID to be defined easily. * * @since Unknown * @access public * * @param string|array $filter The name of the filter. * @param mixed $value The value to filter. * * @return mixed The filtered value. */ function gf_apply_filters( $filter, $value ) { $args = func_get_args(); if ( is_array( $filter ) ) { // func parameters are: $filter, $value $modifiers = array_splice( $filter, 1, count( $filter ) ); $filter = $filter[0]; $args = array_slice( $args, 2 ); } else { //_deprecated_argument( 'gf_apply_filters', '1.9.14.20', "Modifiers should no longer be passed as a separate parameter. Combine the filter name and modifier(s) into an array and pass that array as the first parameter of the function. Example: gf_apply_filters( array( 'action_name', 'mod1', 'mod2' ), \$value, \$arg1, \$arg2 );" ); // func parameters are: $filter, $modifier, $value $modifiers = ! is_array( $value ) ? array( $value ) : $value; $value = $args[2]; $args = array_slice( $args, 3 ); } // Add an empty modifier so the base filter will be applied as well array_unshift( $modifiers, '' ); $args = array_pad( $args, 10, null ); // Apply modified versions of filter foreach ( $modifiers as $modifier ) { $modifier = rgblank( $modifier ) ? '' : sprintf( '_%s', $modifier ); $filter .= $modifier; $value = apply_filters( $filter, $value, $args[0], $args[1], $args[2], $args[3], $args[4], $args[5], $args[6], $args[7], $args[8], $args[9] ); } return $value; } } if ( ! function_exists( 'gf_do_action' ) ) { /** * Gravity Forms pre-processing for do_action. * * Allows additional actions based on form and field ID to be defined easily. * * @since 1.9.14.20 Modifiers should no longer be passed as a separate parameter. * @since 1.9.12 * @access public * * @param string|array $action The action. */ function gf_do_action( $action ) { $args = func_get_args(); if ( is_array( $action ) ) { // Func parameters are: $action, $value $modifiers = array_splice( $action, 1, count( $action ) ); $action = $action[0]; $args = array_slice( $args, 1 ); } else { //_deprecated_argument( 'gf_do_action', '1.9.14.20', "Modifiers should no longer be passed as a separate parameter. Combine the action name and modifier(s) into an array and pass that array as the first parameter of the function. Example: gf_do_action( array( 'action_name', 'mod1', 'mod2' ), \$arg1, \$arg2 );" ); // Func parameters are: $action, $modifier, $value $modifiers = ! is_array( $args[1] ) ? array( $args[1] ) : $args[1]; $args = array_slice( $args, 2 ); } // Add an empty modifier so the base filter will be applied as well array_unshift( $modifiers, '' ); $args = array_pad( $args, 10, null ); // Apply modified versions of filter foreach ( $modifiers as $modifier ) { $modifier = rgblank( $modifier ) ? '' : sprintf( '_%s', $modifier ); $action .= $modifier; do_action( $action, $args[0], $args[1], $args[2], $args[3], $args[4], $args[5], $args[6], $args[7], $args[8], $args[9] ); } } } if ( ! function_exists( 'gf_has_filters' ) ) { /** * Determines if a callback has been registered for the specified filter. * * @since 2.4.18 * * @param array $filter An array containing the filter tag and modifiers. * @param bool|callable $function_to_check The optional callback to check for. * * @return bool */ function gf_has_filters( $filter, $function_to_check = false ) { $modifiers = array_splice( $filter, 1, count( $filter ) ); $filter = $filter[0]; // Adding empty modifier for the base filter. array_unshift( $modifiers, '' ); foreach ( $modifiers as $modifier ) { $modifier = rgblank( $modifier ) ? '' : sprintf( '_%s', $modifier ); $filter .= $modifier; if ( has_filter( $filter, $function_to_check ) ) { return true; } } return false; } } if ( ! function_exists( 'gf_has_filter' ) ) { /** * Determines if a callback has been registered for the specified filter. * * @since 2.4.18 * * @param array $filter An array containing the filter tag and modifiers. * @param bool|callable $function_to_check The optional callback to check for. * * @return bool */ function gf_has_filter( $filter, $function_to_check = false ) { return gf_has_filters( $filter, $function_to_check ); } } if ( ! function_exists( 'gf_has_action' ) ) { /** * Determines if a callback has been registered for the specified action. * * @since 2.4.18 * * @param array $action An array containing the action tag and modifiers. * @param bool|callable $function_to_check The optional callback to check for. * * @return bool */ function gf_has_action( $action, $function_to_check = false ) { return gf_has_filters( $action, $function_to_check ); } }