';
}
}
public static function maybe_get_scroll_js( $id ) {
$offset = apply_filters( 'frm_scroll_offset', 4, array( 'form_id' => $id ) );
if ( $offset != - 1 ) {
self::get_scroll_js( $id );
}
}
public static function get_scroll_js( $form_id ) {
echo '';
}
/**
* @since 3.0
*/
public static function actions_dropdown( $atts ) {
if ( FrmAppHelper::is_admin_page( 'formidable' ) ) {
$status = $atts['status'];
$form_id = isset( $atts['id'] ) ? $atts['id'] : FrmAppHelper::get_param( 'id', 0, 'get', 'absint' );
$trash_link = self::delete_trash_info( $form_id, $status );
$links = self::get_action_links( $form_id, $status );
include( FrmAppHelper::plugin_path() . '/classes/views/frm-forms/actions-dropdown.php' );
}
}
/**
* @since 3.0
*/
public static function get_action_links( $form_id, $form ) {
if ( ! is_object( $form ) ) {
$form = FrmForm::getOne( $form_id );
}
$actions = array();
$trash_links = self::delete_trash_links( $form_id );
if ( 'trash' == $form->status ) {
$actions['restore'] = $trash_links['restore'];
if ( current_user_can( 'frm_delete_forms' ) ) {
$actions['trash'] = $trash_links['delete'];
}
} elseif ( current_user_can( 'frm_edit_forms' ) ) {
$duplicate_link = '?page=formidable&frm_action=duplicate&id=' . $form_id;
if ( $form->is_template ) {
$actions['frm_duplicate'] = array(
'url' => wp_nonce_url( $duplicate_link ),
'label' => __( 'Create Form from Template', 'formidable' ),
'icon' => 'frm_icon_font frm_clone_icon',
);
} else {
$actions['duplicate'] = array(
'url' => wp_nonce_url( $duplicate_link ),
'label' => __( 'Duplicate Form', 'formidable' ),
'icon' => 'frm_icon_font frm_clone_icon',
);
}
$actions['trash'] = self::delete_trash_info( $form_id, $form->status );
}//end if
return $actions;
}
public static function edit_form_link( $data ) {
$form_id = self::get_form_id_from_data( $data );
if ( ! $form_id ) {
return '';
}
$label = self::edit_form_link_label( $data );
$link = '' . esc_html( $label ) . '';
return $link;
}
public static function edit_form_link_label( $data ) {
$name = self::get_form_name_from_data( $data );
if ( ! $name ) {
return __( '(no title)', 'formidable' );
}
return FrmAppHelper::truncate( $name, 40 );
}
/**
* @param mixed $data
* @return int
*/
private static function get_form_id_from_data( $data ) {
if ( is_object( $data ) ) {
$form_id = $data->id;
} else {
$form_id = $data;
}
return $form_id;
}
/**
* @param mixed $data
* @return string
*/
private static function get_form_name_from_data( $data ) {
if ( is_object( $data ) ) {
$form_name = $data->name;
} else {
$form_id = $data;
$form_name = FrmForm::getName( $form_id );
}
return $form_name;
}
public static function delete_trash_link( $id, $status, $length = 'label' ) {
$link_details = self::delete_trash_info( $id, $status );
return self::format_link_html( $link_details, $length );
}
/**
* @since 3.0
*/
public static function format_link_html( $link_details, $length = 'label' ) {
$link = '';
if ( ! empty( $link_details ) ) {
$link = ' $value ) {
$link .= ' data-' . esc_attr( $data ) . '="' . esc_attr( $value ) . '"';
}
} elseif ( isset( $link_details['confirm'] ) ) {
$link .= ' onclick="return confirm(\'' . esc_attr( $link_details['confirm'] ) . '\')"';
}
$label = ( isset( $link_details[ $length ] ) ? $link_details[ $length ] : $link_details['label'] );
if ( $length == 'icon' && isset( $link_details[ $length ] ) ) {
$label = '';
$link .= ' aria-label="' . esc_attr( $link_details['label'] ) . '"';
}
$link .= '>' . $label . '';
}
return $link;
}
/**
* @since 3.0
*/
public static function delete_trash_info( $id, $status ) {
$labels = self::delete_trash_links( $id );
if ( 'trash' == $status ) {
$info = $labels['restore'];
} elseif ( current_user_can( 'frm_delete_forms' ) ) {
if ( EMPTY_TRASH_DAYS ) {
$info = $labels['trash'];
} else {
$info = $labels['delete'];
}
} else {
$info = array();
}
return $info;
}
/**
* @since 3.0
*/
public static function delete_trash_links( $id ) {
$current_page = FrmAppHelper::get_simple_request( array( 'param' => 'form_type' ) );
$base_url = '?page=formidable&form_type=' . $current_page . '&id=' . $id;
return array(
'restore' => array(
'label' => __( 'Restore from Trash', 'formidable' ),
'short' => __( 'Restore', 'formidable' ),
'url' => wp_nonce_url( $base_url . '&frm_action=untrash', 'untrash_form_' . absint( $id ) ),
),
'trash' => array(
'label' => __( 'Move Form to Trash', 'formidable' ),
'short' => __( 'Trash', 'formidable' ),
'url' => wp_nonce_url( $base_url . '&frm_action=trash', 'trash_form_' . absint( $id ) ),
'icon' => 'frm_icon_font frm_delete_icon',
'data' => array(
'frmverify' => __( 'Do you want to move this form to the trash?', 'formidable' ),
'frmverify-btn' => 'frm-button-red',
),
),
'delete' => array(
'label' => __( 'Delete Permanently', 'formidable' ),
'short' => __( 'Delete', 'formidable' ),
'url' => wp_nonce_url( $base_url . '&frm_action=destroy', 'destroy_form_' . absint( $id ) ),
'confirm' => __( 'Are you sure you want to delete this form and all its entries?', 'formidable' ),
'icon' => 'frm_icon_font frm_delete_icon',
'data' => array(
'frmverify' => __( 'This will permanently delete the form and all its entries. This is irreversible. Are you sure you want to continue?', 'formidable' ),
'frmverify-btn' => 'frm-button-red',
),
),
);
}
/**
* @since 3.0
*/
public static function css_classes() {
$classes = array(
'frm_total' => array(
'label' => __( 'Total', 'formidable' ),
'title' => __( 'Add this to a read-only field to display the text in bold without a border or background.', 'formidable' ),
),
'frm_total_big' => array(
'label' => __( 'Big Total', 'formidable' ),
'title' => __( 'Add this to a read-only field to display the text in large, bold text without a border or background.', 'formidable' ),
),
'frm_scroll_box' => array(
'label' => __( 'Scroll Box', 'formidable' ),
'title' => __( 'If you have many checkbox or radio button options, you may add this class to allow your user to easily scroll through the options. Or add a scrolling area around content in an HTML field.', 'formidable' ),
),
'frm_first' => array(
'label' => __( 'First', 'formidable' ),
'title' => __( 'Add this to the first field in each row along with a width. ie frm_first frm4', 'formidable' ),
),
'frm_alignright' => __( 'Right', 'formidable' ),
'frm_grid_first' => __( 'First Grid Row', 'formidable' ),
'frm_grid' => __( 'Even Grid Row', 'formidable' ),
'frm_grid_odd' => __( 'Odd Grid Row', 'formidable' ),
'frm_color_block' => array(
'label' => __( 'Color Block', 'formidable' ),
'title' => __( 'Add a background color to the field or section.', 'formidable' ),
),
'frm_capitalize' => array(
'label' => __( 'Capitalize', 'formidable' ),
'title' => __( 'Automatically capitalize the first letter in each word.', 'formidable' ),
),
);
return apply_filters( 'frm_layout_classes', $classes );
}
public static function grid_classes() {
return array(
'frm_half' => '1/2',
'frm_third' => '1/3',
'frm_two_thirds' => '2/3',
'frm_fourth' => '1/4',
'frm_three_fourths' => '3/4',
'frm_sixth' => '1/6',
'frm10' => '5/6',
'frm12' => '100%',
);
}
/**
* @since 3.0
*/
public static function style_class_label( $style, $class ) {
$label = '';
if ( empty( $style ) ) {
$label = $class;
} elseif ( ! is_array( $style ) ) {
$label = $style;
} elseif ( isset( $style['label'] ) ) {
$label = $style['label'];
}
return $label;
}
public static function status_nice_name( $status ) {
$nice_names = array(
'draft' => __( 'Draft', 'formidable' ),
'trash' => __( 'Trash', 'formidable' ),
'publish' => __( 'Published', 'formidable' ),
);
if ( ! in_array( $status, array_keys( $nice_names ) ) ) {
$status = 'publish';
}
$name = $nice_names[ $status ];
return $name;
}
/**
* Renders a template icon based on the given categories.
*
* @param array $categories The categories to render the icon for.
* @param array $atts {
* Optional. An array of attributes for rendering.
* @type string $html 'span' or 'div'. Default 'span'.
* @type boolean $bg Whether to add a background color or not. Default false.
* }
*
* @return void
*/
public static function template_icon( $categories, $atts = array() ) {
// Define defaults.
$defaults = array(
'bg' => true,
);
$atts = array_merge( $defaults, $atts );
// Filter out ignored categories.
$ignore = self::ignore_template_categories();
$categories = array_diff( $categories, $ignore );
// Define icons mapping.
$icons = array(
'WooCommerce' => array( 'woocommerce', 'var(--purple)' ),
'Post' => array( 'wordpress', 'rgb(0,160,210)' ),
'User Registration' => array( 'register', 'var(--pink)' ),
'Registration and Signup' => array( 'register', 'var(--pink)' ),
'PayPal' => array( 'paypal' ),
'Stripe' => array( 'credit_card', 'var(--green)' ),
'Twilio' => array( 'sms' ),
'Payment' => array( 'credit_card' ),
'Order Form' => array( 'product' ),
'Finance' => array( 'total' ),
'Health and Wellness' => array( 'heart', 'var(--pink)' ),
'Event Planning' => array( 'calendar', 'var(--orange)' ),
'Real Estate' => array( 'house' ),
'Nonprofit' => array( 'heart_solid' ),
'Calculator' => array( 'calculator', 'var(--purple)' ),
'Quiz' => array( 'percent' ),
'Registrations' => array( 'address_card' ),
'Customer Service' => array( 'users_solid' ),
'Education' => array( 'pencil' ),
'Marketing' => array( 'eye' ),
'Feedback' => array( 'smile' ),
'Business Operations' => array( 'case' ),
'Contact Form' => array( 'email' ),
'Conversational Forms' => array( 'chat_forms' ),
'Survey' => array( 'chat_forms', 'var(--orange)' ),
'Application' => array( 'align_right' ),
'Signature' => array( 'signature' ),
'' => array( 'align_right' ),
);
// Determine the icon to be used.
$icon = $icons[''];
if ( count( $categories ) === 1 ) {
$category = reset( $categories );
$icon = isset( $icons[ $category ] ) ? $icons[ $category ] : $icon;
} elseif ( ! empty( $categories ) ) {
$icons = array_intersect_key( $icons, array_flip( $categories ) );
$icon = reset( $icons );
}
// Prepare variables for output.
$icon_name = $icon[0];
$bg_color = isset( $icon[1] ) ? $icon[1] : '';
// Render the icon.
echo '';
FrmAppHelper::icon_by_class( 'frmfont frm_' . $icon_name . '_icon' );
echo '';
}
/**
* Retrieves the list of template categories to ignore.
*
* @since 4.03.01
*
* @return string[] Array of categories to ignore.
*/
public static function ignore_template_categories() {
return array( 'Business', 'Elite', 'Personal', 'Creator', 'Basic', 'free' );
}
/**
* Get template install link.
*
* @since 4.02
*
* @param array $template Template details.
* @param array $args Additional arguments.
* @return array The link attributes.
*/
public static function get_template_install_link( $template, $args ) {
$defaults = array(
'class' => 'install-now',
'href' => 'href',
'atts' => true,
);
if ( ! empty( $template['url'] ) ) {
$link = array(
'url' => $template['url'],
'label' => __( 'Create Form', 'formidable' ),
'class' => 'frm-install-template',
'href' => 'rel',
'atts' => '',
);
} elseif ( self::plan_is_allowed( $args ) ) {
$link = array(
'url' => FrmAppHelper::admin_upgrade_link( 'addons', 'account/downloads/' ) . '&utm_content=' . $template['slug'],
'label' => __( 'Renew', 'formidable' ),
);
} else {
$link = array(
'url' => $args['pricing'],
'label' => __( 'Upgrade', 'formidable' ),
);
}
return array_merge( $defaults, $link );
}
/**
* Is the template included with the license type?
*
* @since 4.02.02
*
* @param array $args
* @return bool
*/
public static function plan_is_allowed( $args ) {
if ( empty( $args['license_type'] ) ) {
return false;
}
$plans = array( 'free', 'personal', 'business', 'elite' );
$license_type = strtolower( $args['license_type'] );
$plan_required = strtolower( $args['plan_required'] );
$included = $license_type === $plan_required;
if ( $included || ! in_array( $plan_required, $plans, true ) ) {
return $included;
}
foreach ( $plans as $plan ) {
if ( $included || $plan === $license_type ) {
break;
}
$included = $plan === $plan_required;
}
return $included;
}
/**
* If a template or add-on cannot be installed, show a message
* about which plan is required.
*
* @since 4.0
*/
public static function show_plan_required( $requires, $link ) {
if ( empty( $requires ) ) {
return;
}
?>
$category ) {
if ( in_array( $category, $plans, true ) ) {
unset( $item['categories'][ $k ] );
if ( in_array( $category, array( 'Creator', 'Personal' ), true ) ) {
// Show the current package name.
$category = 'Plus';
}
return $category;
}
}
return false;
}
/**
* Checks for warnings to be displayed after form settings are saved.
*
* @since 4.04
*
* @param array $values The $_POST array, which contains values submitted in a form.
*
* @return array An array of warnings or an empty array.
*/
public static function check_for_warnings( $values ) {
$warnings = array();
$redirect_warning = self::check_redirect_url_for_unsafe_params( $values );
if ( $redirect_warning ) {
$warnings[] = $redirect_warning;
}
return apply_filters( 'frm_check_for_warnings', $warnings, $values );
}
/**
* Checks the redirect URL for params whose names are reserved words.
*
* @since 4.04
*
* @param array $values The $_POST array, which contains the values submitted in a form.
*
* @return bool|string A warning message about unsafe params or false.
*/
private static function check_redirect_url_for_unsafe_params( $values ) {
if ( ! isset( $values['options'] ) ) {
return false;
}
$options = $values['options'];
FrmAppHelper::sanitize_with_html( $options );
if ( ( ! isset( $options['success_action'] ) ) || $options['success_action'] !== 'redirect' || ! isset( $options['success_url'] ) ) {
return false;
}
$unsafe_params_in_redirect = self::get_unsafe_params( $options['success_url'] );
return self::create_unsafe_param_warning( $unsafe_params_in_redirect );
}
/**
* Returns an array of params whose names are reserved words in the specified URL.
*
* @since 4.04
*
* @param string $url The URL whose params are being checked.
*
* @return array An array of params whose names are reserved words or an empty array.
*/
private static function get_unsafe_params( $url ) {
$redirect_components = parse_url( $url );
if ( empty( $redirect_components['query'] ) ) {
return array();
}
parse_str( $redirect_components['query'], $redirect_params );
$redirect_param_names = array_keys( $redirect_params );
$reserved_words = self::reserved_words();
$unsafe_params_in_redirect = array_intersect( $redirect_param_names, $reserved_words );
return array_values( $unsafe_params_in_redirect );
}
/**
* Returns a warning if reserved words have been used as param names in the redirect URL.
*
* @since 4.04
*
* @param array $unsafe_params_in_redirect Array of params from the redirect URL whose names are reserved words.
*
* @return bool|string A string with an unsafe param message or false.
*/
private static function create_unsafe_param_warning( $unsafe_params_in_redirect ) {
$count = count( $unsafe_params_in_redirect );
$caution = esc_html__( 'Is this intentional?', 'formidable' );
$reserved_words_intro = esc_html__( 'See the list of reserved words in WordPress.', 'formidable' );
$reserved_words_link = ' ' . $reserved_words_intro . '';
if ( $count === 0 ) {
return false;
}
if ( $count == 1 ) {
/* translators: %s: the name of a single parameter in the redirect URL */
return sprintf( esc_html__( 'The redirect URL is using the parameter "%s", which is reserved by WordPress. ', 'formidable' ), $unsafe_params_in_redirect[0] ) . $caution . $reserved_words_link;
}
$unsafe_params_string = implode( '", "', $unsafe_params_in_redirect );
/* translators: %s: the names of two or more parameters in the redirect URL, separated by commas */
return sprintf( esc_html__( 'The redirect URL is using the parameters "%s", which are reserved by WordPress. ', 'formidable' ), $unsafe_params_string ) . $caution . $reserved_words_link;
}
/**
* Returns an array of common reserved words in WordPress.
*
* An edited list of reserved terms from the Codex.
* https://codex.wordpress.org/Reserved_Terms
*
* @since 4.04
*
* @return array Array of WordPress reserved words.
*/
public static function reserved_words() {
return array(
'id',
'attachment',
'author',
'author_name',
'calendar',
'cat',
'category',
'category_name',
'cpage',
'custom',
'day',
'date',
'error',
'feed',
'hour',
'm',
'minute',
'more',
'name',
'order',
'p',
'page',
'page_id',
'paged',
'pb',
'post',
'posts',
'preview',
's',
'search',
'second',
'sentence',
'tag',
'taxonomy',
'tb',
'term',
'terms',
'theme',
'title',
'type',
'w',
'year',
);
}
/**
* Make sure the field shortcodes in a url always add the sanitize_url=1 option if nothing is defined.
* This is to prevent some field characters like ', @, and | from being stripped from the redirect URL.
*
* @since 5.0.16
*
* @param string $url
* @param int $form_id
* @return string
*/
public static function maybe_add_sanitize_url_attr( $url, $form_id ) {
if ( false === strpos( $url, '[' ) ) {
// Do nothing if no shortcodes are detected.
return $url;
}
$parsed = wp_parse_url( $url );
if ( empty( $parsed['query'] ) ) {
// Do nothing if no query can be detected in the url string.
return $url;
}
$original_query = $parsed['query'];
$query = $parsed['query'];
$shortcodes = FrmFieldsHelper::get_shortcodes( $query, $form_id );
if ( empty( $shortcodes[0] ) ) {
// No shortcodes found, do nothing.
return $url;
}
foreach ( $shortcodes[0] as $key => $shortcode ) {
$options = trim( $shortcodes[3][ $key ] );
if ( in_array( $shortcodes[1][ $key ], array( 'if ' ), true ) ) {
// Skip if shortcodes.
continue;
}
if ( false !== strpos( $options, 'sanitize_url=' ) || false !== strpos( $options, 'sanitize=' ) ) {
// A sanitize option is already set so leave it alone.
continue;
}
$new_shortcode = '[' . $shortcodes[2][ $key ];
if ( $options ) {
$new_shortcode .= ' ' . $options;
}
$new_shortcode .= ' sanitize_url=1]';
$query = str_replace( $shortcode, $new_shortcode, $query );
}//end foreach
if ( $query === $original_query ) {
return $url;
}
return str_replace( $original_query, $query, $url );
}
/**
* Check if Pro isn't up to date yet.
* If Pro is active but using a version earlier than v6.2 fallback to Pro for AJAX submit (so things don't all happen twice).
*
* @since 6.2
*
* @return bool
*/
public static function should_use_pro_for_ajax_submit() {
return is_callable( 'FrmProForm::is_ajax_on' ) && ! is_callable( 'FrmProFormsHelper::lite_supports_ajax_submit' );
}
/**
* Outputs the appropriate button text in the publish box.
*
* @return void
*/
public static function publish_box_button_text() {
$is_new_template = FrmAppHelper::simple_get( 'new_template' );
$action = FrmAppHelper::simple_get( 'frm_action' );
if ( ( 'edit' === $action || 'settings' === $action ) && $is_new_template ) {
esc_html_e( 'Save', 'formidable' );
} else {
esc_html_e( 'Update', 'formidable' );
}
}
/**
* @since 4.02
* @deprecated 6.7
*/
public static function template_install_html( $link, $class = '' ) {
_deprecated_function( __METHOD__, '6.7' );
}
/**
* Check an array of templates, determine how many the logged in user can use
*
* @deprecated 6.7
*
* @param array $templates
* @param array $args
* @return int
*/
public static function available_count( $templates, $args ) {
_deprecated_function( __METHOD__, '6.7' );
return 0;
}
}