| @@ -47,8 +47,15 @@ | ||
| 47 | 47 | add_filter( 'manage_toplevel_page_formidable_columns', 'FrmFormsController::get_columns', 0 ); |
| 48 | 48 | add_filter( 'manage_toplevel_page_formidable_sortable_columns', 'FrmFormsController::get_sortable_columns' ); |
| 49 | 49 | } |
| 50 | 50 | |
| 51 | + /** | |
| 52 | + * Runs on admin head of the formidable forms page. | |
| 53 | + * | |
| 54 | + * @since 6.32 This adds screen options. | |
| 55 | + * | |
| 56 | + * @return void | |
| 57 | + */ | |
| 51 | 58 | public static function head() { |
| 52 | 59 | if ( wp_is_mobile() ) { |
| 53 | 60 | wp_enqueue_script( 'jquery-touch-punch' ); |
| 54 | 61 | } |
| @@ -276,8 +283,12 @@ | ||
| 276 | 283 | if ( $antispam_is_on !== $antispam_was_on ) { |
| 277 | 284 | FrmAntiSpam::clear_caches(); |
| 278 | 285 | } |
| 279 | 286 | |
| 287 | + // Handle captcha field inclusion | |
| 288 | + $include_captcha = isset( $_POST['frm_include_captcha'] ) && '1' === $_POST['frm_include_captcha']; // phpcs:ignore WordPress.Security.NonceVerification.Missing | |
| 289 | + self::handle_captcha_field( $id, $include_captcha ); | |
| 290 | + | |
| 280 | 291 | $message = __( 'Settings Successfully Updated', 'formidable' ); |
| 281 | 292 | |
| 282 | 293 | self::get_settings_vars( $id, array(), compact( 'message', 'warnings' ) ); |
| 283 | 294 | } |
| @@ -292,8 +303,46 @@ | ||
| 292 | 303 | return ! empty( $form->options['antispam'] ); |
| 293 | 304 | } |
| 294 | 305 | |
| 295 | 306 | /** |
| 307 | + * Handle captcha field inclusion in form | |
| 308 | + * | |
| 309 | + * @since 6.33 | |
| 310 | + * | |
| 311 | + * @param int $form_id Form ID. | |
| 312 | + * @param bool $include_captcha Whether to include captcha field. | |
| 313 | + * | |
| 314 | + * @return void | |
| 315 | + */ | |
| 316 | + private static function handle_captcha_field( $form_id, $include_captcha ) { | |
| 317 | + $form_fields = FrmField::get_all_for_form( $form_id, '', 'exclude' ); | |
| 318 | + $captcha_field_id = 0; | |
| 319 | + $submit_field_order = 0; | |
| 320 | + | |
| 321 | + foreach ( $form_fields as $field ) { | |
| 322 | + if ( 'captcha' === $field->type ) { | |
| 323 | + $captcha_field_id = $field->id; | |
| 324 | + break; | |
| 325 | + } | |
| 326 | + | |
| 327 | + if ( 'submit' === $field->type ) { | |
| 328 | + $submit_field_order = $field->field_order; | |
| 329 | + } | |
| 330 | + } | |
| 331 | + | |
| 332 | + if ( $include_captcha && ! $captcha_field_id ) { | |
| 333 | + // Create captcha field just before submit button | |
| 334 | + $field_values = FrmFieldsHelper::setup_new_vars( 'captcha', $form_id ); | |
| 335 | + $field_values['name'] = __( 'Captcha', 'formidable' ); | |
| 336 | + $field_values['field_order'] = $submit_field_order > 0 ? $submit_field_order - 1 : 0; | |
| 337 | + FrmField::create( $field_values ); | |
| 338 | + } elseif ( ! $include_captcha && $captcha_field_id ) { | |
| 339 | + // Delete captcha field | |
| 340 | + FrmField::destroy( $captcha_field_id ); | |
| 341 | + } | |
| 342 | + } | |
| 343 | + | |
| 344 | + /** | |
| 296 | 345 | * @param array $values |
| 297 | 346 | * |
| 298 | 347 | * @return void |
| 299 | 348 | */ |
| @@ -1232,17 +1281,27 @@ | ||
| 1232 | 1281 | public static function get_columns( $columns ) { |
| 1233 | 1282 | $columns['cb'] = '<input type="checkbox" />'; |
| 1234 | 1283 | $columns['name'] = esc_html__( 'Form Title', 'formidable' ); |
| 1235 | 1284 | $columns['entries'] = esc_html__( 'Entries', 'formidable' ); |
| 1285 | + $columns['views'] = esc_html__( 'Views', 'formidable' ); | |
| 1236 | 1286 | $columns['id'] = 'ID'; |
| 1237 | 1287 | $columns['form_key'] = esc_html__( 'Key', 'formidable' ); |
| 1238 | 1288 | |
| 1239 | - if ( 'trash' !== FrmAppHelper::simple_get( 'form_type' ) ) { | |
| 1289 | + if ( 'trash' !== FrmAppHelper::simple_get( 'form_type' ) && has_filter( 'frm_form_list_actions' ) ) { | |
| 1290 | + // If there is any filters added, keep this column. | |
| 1240 | 1291 | $columns['shortcode'] = esc_html__( 'Actions', 'formidable' ); |
| 1241 | 1292 | } |
| 1242 | 1293 | |
| 1243 | 1294 | $columns['created_at'] = esc_html__( 'Date', 'formidable' ); |
| 1244 | 1295 | |
| 1296 | + if ( 'trash' !== FrmAppHelper::simple_get( 'form_type' ) ) { | |
| 1297 | + $columns['embeds'] = esc_html__( 'Embeds', 'formidable' ); | |
| 1298 | + $columns['settings'] = '<div class="frm-forms-list-settings-btn-wrapper"><a href="#" class="frm-forms-list-settings-btn">'; | |
| 1299 | + $columns['settings'] .= FrmAppHelper::icon_by_class( 'frmfont frm_settings_icon', array( 'echo' => false ) ); | |
| 1300 | + $columns['settings'] .= '<span class="screen-reader-text">' . esc_html__( 'List settings', 'formidable' ) . '</span>'; | |
| 1301 | + $columns['settings'] .= '</a></div>'; | |
| 1302 | + } | |
| 1303 | + | |
| 1245 | 1304 | add_screen_option( |
| 1246 | 1305 | 'per_page', |
| 1247 | 1306 | array( |
| 1248 | 1307 | 'label' => __( 'Forms', 'formidable' ), |
| @@ -1528,8 +1587,13 @@ | ||
| 1528 | 1587 | 'function' => array( 'FrmFormActionsController', 'email_settings' ), |
| 1529 | 1588 | 'id' => 'frm_notification_settings', |
| 1530 | 1589 | 'icon' => 'frmfont frm_notification_check_icon', |
| 1531 | 1590 | ), |
| 1591 | + 'spam' => array( | |
| 1592 | + 'name' => __( 'Spam', 'formidable' ), | |
| 1593 | + 'function' => array( self::class, 'spam_settings' ), | |
| 1594 | + 'icon' => 'frmfont frm_shield_check2_icon', | |
| 1595 | + ), | |
| 1532 | 1596 | 'permissions' => array( |
| 1533 | 1597 | 'name' => __( 'Form Permissions', 'formidable' ), |
| 1534 | 1598 | 'icon' => 'frmfont frm_lock_closed2_icon', |
| 1535 | 1599 | 'html_class' => 'frm_show_upgrade_tab frm_noallow', |
| @@ -1647,18 +1711,16 @@ | ||
| 1647 | 1711 | include FrmAppHelper::plugin_path() . '/classes/views/frm-forms/settings-advanced.php'; |
| 1648 | 1712 | } |
| 1649 | 1713 | |
| 1650 | 1714 | /** |
| 1715 | + * @since 6.33 | |
| 1716 | + * | |
| 1651 | 1717 | * @param array $values |
| 1652 | 1718 | * |
| 1653 | 1719 | * @return void |
| 1654 | 1720 | */ |
| 1655 | - public static function render_spam_settings( $values ) { | |
| 1656 | - if ( function_exists( 'akismet_http_post' ) ) { | |
| 1657 | - include FrmAppHelper::plugin_path() . '/classes/views/frm-forms/spam-settings/akismet.php'; | |
| 1658 | - } | |
| 1659 | - include FrmAppHelper::plugin_path() . '/classes/views/frm-forms/spam-settings/stopforumspam.php'; | |
| 1660 | - include FrmAppHelper::plugin_path() . '/classes/views/frm-forms/spam-settings/antispam.php'; | |
| 1721 | + public static function spam_settings( $values ) { | |
| 1722 | + include FrmAppHelper::plugin_path() . '/classes/views/frm-forms/spam-settings.php'; | |
| 1661 | 1723 | } |
| 1662 | 1724 | |
| 1663 | 1725 | /** |
| 1664 | 1726 | * @since 4.0 |
| @@ -1736,9 +1798,9 @@ | ||
| 1736 | 1798 | $linked_forms = array(); |
| 1737 | 1799 | $col = 'one'; |
| 1738 | 1800 | $settings_tab = FrmAppHelper::is_admin_page( 'formidable' ); |
| 1739 | 1801 | $cond_shortcodes = apply_filters( 'frm_conditional_shortcodes', array() ); |
| 1740 | - $entry_shortcodes = self::get_shortcode_helpers( $settings_tab ); | |
| 1802 | + $entry_shortcodes = self::get_shortcode_helpers( $settings_tab, $form_id ); | |
| 1741 | 1803 | $advanced_helpers = self::advanced_helpers( compact( 'fields', 'form_id' ) ); |
| 1742 | 1804 | |
| 1743 | 1805 | if ( 'default' === $template_path || ! file_exists( $template_path ) ) { |
| 1744 | 1806 | include FrmAppHelper::plugin_path() . '/classes/views/shared/mb_adv_info.php'; |
| @@ -1789,8 +1851,126 @@ | ||
| 1789 | 1851 | return apply_filters( 'frm_advanced_helpers', $advanced_helpers, $atts ); |
| 1790 | 1852 | } |
| 1791 | 1853 | |
| 1792 | 1854 | /** |
| 1855 | + * Adds a shortcode for each part of a multi-part field to the field shortcode list, | |
| 1856 | + * so a single part can be used on its own, like [25 show=first] for a Name field. | |
| 1857 | + * | |
| 1858 | + * @since 6.35 | |
| 1859 | + * | |
| 1860 | + * @param array $atts Includes 'field'. | |
| 1861 | + * | |
| 1862 | + * @return void | |
| 1863 | + */ | |
| 1864 | + public static function field_part_shortcodes( $atts ) { | |
| 1865 | + $field = $atts['field']; | |
| 1866 | + | |
| 1867 | + foreach ( self::get_field_parts( $field ) as $part => $label ) { | |
| 1868 | + FrmFormsHelper::insert_opt_html( | |
| 1869 | + array( | |
| 1870 | + 'id' => $field->id . ' show=' . $part, | |
| 1871 | + 'key' => $field->field_key . ' show=' . $part, | |
| 1872 | + // Keep the part label and the option out of the truncated text so they stay readable. | |
| 1873 | + 'key_label' => $field->field_key, | |
| 1874 | + 'key_suffix' => ' show=' . $part, | |
| 1875 | + 'name' => $field->name, | |
| 1876 | + 'name_suffix' => ' (' . $label . ')', | |
| 1877 | + 'type' => $field->type, | |
| 1878 | + 'class' => 'frm-customize-list dropdown-item', | |
| 1879 | + ) | |
| 1880 | + ); | |
| 1881 | + unset( $part, $label ); | |
| 1882 | + } | |
| 1883 | + } | |
| 1884 | + | |
| 1885 | + /** | |
| 1886 | + * Gets the parts of a multi-part field that can be shown on their own with a show= shortcode option. | |
| 1887 | + * | |
| 1888 | + * @since 6.35 | |
| 1889 | + * | |
| 1890 | + * @param stdClass $field | |
| 1891 | + * | |
| 1892 | + * @return array Part labels keyed by the show= option value. | |
| 1893 | + */ | |
| 1894 | + private static function get_field_parts( $field ) { | |
| 1895 | + $parts = array(); | |
| 1896 | + | |
| 1897 | + if ( 'name' === $field->type ) { | |
| 1898 | + $parts = self::get_name_field_parts( $field ); | |
| 1899 | + } elseif ( 'address' === $field->type ) { | |
| 1900 | + $parts = self::get_address_field_parts( $field ); | |
| 1901 | + } | |
| 1902 | + | |
| 1903 | + /** | |
| 1904 | + * Allows add-ons to add the parts of their own multi-part fields. | |
| 1905 | + * | |
| 1906 | + * @since 6.35 | |
| 1907 | + * | |
| 1908 | + * @param array $parts Part labels keyed by the show= option value. | |
| 1909 | + * @param stdClass $field The field the parts belong to. | |
| 1910 | + */ | |
| 1911 | + return apply_filters( 'frm_field_parts_for_shortcodes', $parts, $field ); | |
| 1912 | + } | |
| 1913 | + | |
| 1914 | + /** | |
| 1915 | + * Gets the parts of a Name field that are in use. Only the parts included in the | |
| 1916 | + * selected name layout hold a value, so the rest would always show as blank. | |
| 1917 | + * | |
| 1918 | + * @since 6.35 | |
| 1919 | + * | |
| 1920 | + * @param stdClass $field | |
| 1921 | + * | |
| 1922 | + * @return array Part labels keyed by the show= option value, in layout order. | |
| 1923 | + */ | |
| 1924 | + private static function get_name_field_parts( $field ) { | |
| 1925 | + $labels = array( | |
| 1926 | + 'first' => __( 'First', 'formidable' ), | |
| 1927 | + 'middle' => __( 'Middle', 'formidable' ), | |
| 1928 | + 'last' => __( 'Last', 'formidable' ), | |
| 1929 | + ); | |
| 1930 | + $layout = FrmField::get_option( $field, 'name_layout' ); | |
| 1931 | + | |
| 1932 | + if ( ! $layout ) { | |
| 1933 | + $layout = 'first_last'; | |
| 1934 | + } | |
| 1935 | + | |
| 1936 | + // The layout option names the parts in use, in display order, like first_middle_last. | |
| 1937 | + $parts = array(); | |
| 1938 | + | |
| 1939 | + foreach ( explode( '_', $layout ) as $part ) { | |
| 1940 | + if ( isset( $labels[ $part ] ) ) { | |
| 1941 | + $parts[ $part ] = $labels[ $part ]; | |
| 1942 | + } | |
| 1943 | + unset( $part ); | |
| 1944 | + } | |
| 1945 | + | |
| 1946 | + return $parts; | |
| 1947 | + } | |
| 1948 | + | |
| 1949 | + /** | |
| 1950 | + * Gets the parts of an Address field that are in use. The address type decides which | |
| 1951 | + * parts are on the form, so the rest would always show as blank. | |
| 1952 | + * | |
| 1953 | + * @since 6.35 | |
| 1954 | + * | |
| 1955 | + * @param stdClass $field | |
| 1956 | + * | |
| 1957 | + * @return array Part labels keyed by the show= option value. | |
| 1958 | + */ | |
| 1959 | + private static function get_address_field_parts( $field ) { | |
| 1960 | + $parts = FrmFieldAddress::get_part_labels(); | |
| 1961 | + $address_type = FrmField::get_option( $field, 'address_type' ); | |
| 1962 | + | |
| 1963 | + if ( in_array( $address_type, array( 'us', 'generic' ), true ) ) { | |
| 1964 | + unset( $parts['country'] ); | |
| 1965 | + } elseif ( 'europe' === $address_type ) { | |
| 1966 | + unset( $parts['state'] ); | |
| 1967 | + } | |
| 1968 | + | |
| 1969 | + return $parts; | |
| 1970 | + } | |
| 1971 | + | |
| 1972 | + /** | |
| 1793 | 1973 | * Get an array of the options to display in the advanced tab |
| 1794 | 1974 | * of the customization panel |
| 1795 | 1975 | * |
| 1796 | 1976 | * @since 2.0.6 |
| @@ -1845,12 +2025,13 @@ | ||
| 1845 | 2025 | * |
| 1846 | 2026 | * @since 2.0.6 |
| 1847 | 2027 | * |
| 1848 | 2028 | * @param bool $settings_tab |
| 2029 | + * @param int $form_id | |
| 1849 | 2030 | * |
| 1850 | 2031 | * @return array |
| 1851 | 2032 | */ |
| 1852 | - private static function get_shortcode_helpers( $settings_tab ) { | |
| 2033 | + private static function get_shortcode_helpers( $settings_tab, $form_id = 0 ) { | |
| 1853 | 2034 | $entry_shortcodes = array( |
| 1854 | 2035 | 'id' => __( 'Entry ID', 'formidable' ), |
| 1855 | 2036 | 'key' => __( 'Entry Key', 'formidable' ), |
| 1856 | 2037 | 'post_id' => __( 'Post ID', 'formidable' ), |
| @@ -1876,10 +2057,11 @@ | ||
| 1876 | 2057 | * @since 2.0.6 |
| 1877 | 2058 | * |
| 1878 | 2059 | * @param array $entry_shortcodes |
| 1879 | 2060 | * @param bool $settings_tab |
| 2061 | + * @param int $form_id | |
| 1880 | 2062 | */ |
| 1881 | - return apply_filters( 'frm_helper_shortcodes', $entry_shortcodes, $settings_tab ); | |
| 2063 | + return apply_filters( 'frm_helper_shortcodes', $entry_shortcodes, $settings_tab, $form_id ); | |
| 1882 | 2064 | } |
| 1883 | 2065 | |
| 1884 | 2066 | /** |
| 1885 | 2067 | * Insert the form class setting into the form. |
| @@ -2215,9 +2397,10 @@ | ||
| 2215 | 2397 | } |
| 2216 | 2398 | |
| 2217 | 2399 | if ( $name === $form->name ) { |
| 2218 | 2400 | // Nothing to change so exit early. |
| 2219 | - wp_send_json_success(); | |
| 2401 | + $form_key = $form->form_key; | |
| 2402 | + wp_send_json_success( compact( 'form_key' ) ); | |
| 2220 | 2403 | } |
| 2221 | 2404 | |
| 2222 | 2405 | $to_update = array( |
| 2223 | 2406 | 'name' => $name, |
| @@ -3695,8 +3878,39 @@ | ||
| 3695 | 3878 | ); |
| 3696 | 3879 | } |
| 3697 | 3880 | |
| 3698 | 3881 | /** |
| 3882 | + * Prints necessary templates for the forms list page. | |
| 3883 | + * | |
| 3884 | + * @since 6.32 | |
| 3885 | + * | |
| 3886 | + * @return void | |
| 3887 | + */ | |
| 3888 | + public static function print_forms_list_templates() { | |
| 3889 | + if ( ! FrmAppHelper::on_form_listing_page() ) { | |
| 3890 | + return; | |
| 3891 | + } | |
| 3892 | + | |
| 3893 | + $screen = get_current_screen(); | |
| 3894 | + | |
| 3895 | + if ( ! $screen ) { | |
| 3896 | + return; | |
| 3897 | + } | |
| 3898 | + | |
| 3899 | + $columns = get_column_headers( $screen ); | |
| 3900 | + $hidden = get_hidden_columns( $screen ); | |
| 3901 | + $skip_cols = array( 'cb', 'name', 'settings' ); | |
| 3902 | + $per_page = get_user_option( 'formidable_page_formidable_per_page' ); | |
| 3903 | + $show_screen_options = $screen->show_screen_options(); | |
| 3904 | + | |
| 3905 | + if ( $per_page < 1 ) { | |
| 3906 | + $per_page = 20; | |
| 3907 | + } | |
| 3908 | + | |
| 3909 | + include FrmAppHelper::plugin_path() . '/classes/views/frm-forms/forms-list-settings.php'; | |
| 3910 | + } | |
| 3911 | + | |
| 3912 | + /** | |
| 3699 | 3913 | * @deprecated 4.0 |
| 3700 | 3914 | * |
| 3701 | 3915 | * @param array $values |
| 3702 | 3916 | * |
| @@ -3704,6 +3918,17 @@ | ||
| 3704 | 3918 | */ |
| 3705 | 3919 | public static function create( $values = array() ) { |
| 3706 | 3920 | _deprecated_function( __METHOD__, '4.0', 'FrmFormsController::update' ); |
| 3707 | 3921 | self::update( $values ); |
| 3922 | + } | |
| 3923 | + | |
| 3924 | + /** | |
| 3925 | + * @deprecated 6.33 | |
| 3926 | + * | |
| 3927 | + * @param array $values | |
| 3928 | + * | |
| 3929 | + * @return void | |
| 3930 | + */ | |
| 3931 | + public static function render_spam_settings( $values ) { | |
| 3932 | + _deprecated_function( __METHOD__, '6.33' ); | |
| 3708 | 3933 | } |
| 3709 | 3934 | } |