__( 'Frontend Form', 'frontend-admin' ), __( 'Post', 'frontend-admin' ) => array( 'new_post' => __( 'New Post Form', 'frontend-admin' ), 'edit_post' => __( 'Edit Post Form', 'frontend-admin' ), 'duplicate_post' => __( 'Duplicate Post Form', 'frontend-admin' ), 'delete_post' => __( 'Delete Post Button', 'frontend-admin' ), 'status_post' => __( 'Post Status Button', 'frontend-admin' ), ), __( 'User', 'frontend-admin' ) => array( 'new_user' => __( 'New User Form', 'frontend-admin' ), 'edit_user' => __( 'Edit User Form', 'frontend-admin' ), 'delete_user' => __( 'Delete User Button', 'frontend-admin' ), ), __( 'Term', 'frontend-admin' ) => array( 'new_term' => __( 'New Taxonomy Form', 'frontend-admin' ), 'edit_term' => __( 'Edit Taxonomy Form', 'frontend-admin' ), 'delete_term' => __( 'Delete Term Button', 'frontend-admin' ), ), ); $form_types = apply_filters( 'frontend_admin/forms/form_types', $form_types ); return $form_types; } function feadmin_user_exists( $id ) { global $wpdb; $count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->users WHERE ID = %d", $id ) ); if ( $count == 1 ) { return true; } return false; } function feadmin_get_field_data( $type = null, $form_fields = false ) { $field_types = array(); if ( ! $form_fields ) { $GLOBALS['only_acf_field_groups'] = 1; } $acf_field_groups = acf_get_field_groups(); $GLOBALS['only_acf_field_groups'] = 0; // bail early if no field groups if ( empty( $acf_field_groups ) ) { die(); } // loop through array and add to field 'choices' if ( $acf_field_groups ) { foreach ( $acf_field_groups as $field_group ) { if ( ! empty( $field_group['frontend_admin_group'] ) ) { continue; } $field_group_fields = acf_get_fields( $field_group['key'] ); if ( is_array( $field_group_fields ) ) { foreach ( $field_group_fields as $acf_field ) { if ( $type ) { if ( ( is_array( $type ) && in_array( $acf_field['type'], $type, true ) ) || ( ! is_array( $type ) && $acf_field['type'] == $type ) ) { $field_types[ $acf_field['key'] ] = $acf_field['label']; } } else { $field_types[ $acf_field['key'] ]['type'] = $acf_field['type']; $field_types[ $acf_field['key'] ]['label'] = $acf_field['label']; $field_types[ $acf_field['key'] ]['name'] = $acf_field['name']; } } } } } return $field_types; } function feadmin_get_user_roles( $exceptions = array(), $all = false ) { if ( ! current_user_can( 'administrator' ) ) { $exceptions[] = 'administrator'; } $user_roles = array(); if ( $all ) { $user_roles['all'] = __( 'All', 'frontend-admin' ); } global $wp_roles; // loop through array and add to field 'choices' foreach ( $wp_roles->roles as $role => $settings ) { if ( ! in_array( strtolower( $role ), $exceptions ) ) { $user_roles[ $role ] = $settings['name']; } } return $user_roles; } function feadmin_get_user_caps( $exceptions = array(), $all = false ) { $user_caps = array(); $data = get_userdata( get_current_user_id() ); if ( is_object( $data ) ) { $current_user_caps = $data->allcaps; foreach ( $current_user_caps as $cap => $true ) { if ( ! in_array( strtolower( $cap ), $exceptions ) ) { $user_caps[ $cap ] = $cap; } } } return $user_caps; } function feadmin_get_acf_group_choices() { $field_group_choices = array(); $acf_field_groups = acf_get_field_groups(); // loop through array and add to field 'choices' if ( is_array( $acf_field_groups ) ) { foreach ( $acf_field_groups as $field_group ) { if ( is_array( $field_group ) && ! isset( $field_group['frontend_admin_group'] ) ) { $field_group_choices[ $field_group['key'] ] = $field_group['title']; } } } return $field_group_choices; } /* add_filter('acf/get_fields', function( $fields, $parent ){ $group = explode( 'acfef_', $parent['key'] ); if( empty( $group[1] ) ) return $fields; return array(); }, 5, 2); */ function feadmin_get_acf_field_choices( $filter = array(), $return = 'label' ) { $all_fields = array(); if ( isset( $filter['groups'] ) ) { $acf_field_groups = $filter['groups']; } else { $acf_field_groups = acf_get_field_groups( $filter ); } // bail early if no field groups if ( empty( $acf_field_groups ) ) { return array(); } foreach ( $acf_field_groups as $group ) { if ( ! is_array( $group ) ) { $group = acf_get_field_group( $group ); } if ( ! empty( $field_group['frontend_admin_group'] ) ) { continue; } $group_fields = acf_get_fields( $group ); if ( is_array( $group_fields ) ) { foreach ( $group_fields as $acf_field ) { if ( ! is_array( $acf_field ) ) { continue; } $acf_field_key = $acf_field['type'] == 'clone' ? $acf_field['__key'] : $acf_field['key']; if ( ! empty( $filter['type'] ) && $filter['type'] == $acf_field['type'] ) { $all_fields[ $acf_field['name'] ] = $acf_field[ $return ]; } else { if ( isset( $filter['groups'] ) ) { $all_fields[ $acf_field_key ] = $acf_field[ $return ]; } else { $all_fields[ $acf_field_key ] = $acf_field[ $return ]; } } } } } return $all_fields; } function feadmin_get_post_type_choices() { $post_type_choices = array(); $args = array(); $output = 'names'; // names or objects, note names is the default $operator = 'and'; // 'and' or 'or' $post_types = get_post_types( $args, $output, $operator ); // loop through array and add to field 'choices' if ( is_array( $post_types ) ) { foreach ( $post_types as $post_type ) { $post_type_choices[ $post_type ] = str_replace( '_', ' ', ucfirst( $post_type ) ); } } return $post_type_choices; } /** * Unserializes stored data without ever instantiating objects. */ function feadmin_maybe_unserialize( $data ) { if ( is_string( $data ) && is_serialized( $data ) ) { return @unserialize( trim( $data ), array( 'allowed_classes' => false ) ); // phpcs:ignore -- allowed_classes is false. } return $data; } /** * Post types that hold plugin, ACF or WordPress internals rather than content. * Creating one of these defines fields, forms or site structure, so a form * submission may only do it for a user who could do the same in wp-admin. */ function feadmin_get_protected_post_types() { $post_types = array( 'admin_form', 'acf-field', 'acf-field-group', 'acf-post-type', 'acf-taxonomy', 'acf-ui-options-page', 'dashboard_page', 'attachment', 'revision', 'nav_menu_item', 'custom_css', 'customize_changeset', 'oembed_cache', 'user_request', 'wp_block', 'wp_template', 'wp_template_part', 'wp_global_styles', 'wp_navigation', 'wp_font_family', 'wp_font_face', ); return apply_filters( 'frontend_admin/protected_post_types', $post_types ); } /** * Whether a submitted post type may be saved by the current user. * * @param mixed $post_type The submitted post type. * @param array $field Optional Post Type field the value came from; its * "Post Types" setting limits the choices. */ function feadmin_can_submit_post_type( $post_type, $field = array() ) { if ( ! is_string( $post_type ) || ! post_type_exists( $post_type ) ) { return false; } if ( ! empty( $field['post_type_options'] ) && ! in_array( $post_type, (array) $field['post_type_options'], true ) ) { return false; } if ( in_array( $post_type, feadmin_get_protected_post_types(), true ) && ! current_user_can( 'manage_options' ) ) { return false; } return true; } /** * Whether a meta key is reserved and must never be written from a form field. * A field's name is used as its meta key, so without this a field named e.g. * wp_capabilities would write straight into a user's roles. * * @param string $name The meta key (field name). * @param string $type The object type: post, user, term or option. */ function feadmin_is_protected_meta_key( $name, $type = 'post' ) { global $wpdb; $name = ltrim( strtolower( (string) $name ) ); $protected = false; // plugin and ACF internals, on any object type foreach ( array( '_acf_', '_fea_' ) as $prefix ) { if ( 0 === strpos( $name, $prefix ) ) { $protected = true; } } if ( 'user' === $type ) { $keys = array( $wpdb->get_blog_prefix() . 'capabilities', $wpdb->get_blog_prefix() . 'user_level', 'session_tokens', 'frontend_admin_manager', ); // covers every site's prefix on multisite, e.g. wp_2_capabilities if ( in_array( $name, $keys, true ) || preg_match( '/(^|_)(capabilities|user_level)$/', $name ) ) { $protected = true; } } if ( 'post' === $type ) { $keys = array( 'form_key', 'admin_form_source', 'admin_form_edited', '_wp_attached_file', '_wp_attachment_metadata', '_edit_lock', '_edit_last', ); if ( in_array( $name, $keys, true ) ) { $protected = true; } } return apply_filters( 'frontend_admin/protected_meta_key', $protected, $name, $type ); } /** * Blocks writes to reserved meta keys at the point every field value is saved, * so sub fields (a group "wp" with a sub field "capabilities") are covered too. */ function feadmin_block_protected_metadata( $pre, $post_id, $name, $value = '', $hidden = false ) { if ( null !== $pre ) { return $pre; } $type = 'post'; if ( is_string( $post_id ) && ! is_numeric( $post_id ) ) { if ( 0 === strpos( $post_id, 'user_' ) ) { $type = 'user'; } elseif ( 0 === strpos( $post_id, 'term_' ) ) { $type = 'term'; } elseif ( 0 !== strpos( $post_id, 'post_' ) ) { $type = 'option'; } } if ( feadmin_is_protected_meta_key( $name, $type ) ) { return false; } // hidden meta is stored with an underscore prefix if ( $hidden && feadmin_is_protected_meta_key( '_' . $name, $type ) ) { return false; } return $pre; } add_filter( 'acf/pre_update_metadata', 'feadmin_block_protected_metadata', 5, 5 ); /** * Whether the current user may do something that normally needs $capability, * either because they hold it or because the form's permission rule they * matched grants it through the "Special Permissions" setting. * * @param string $permission The special permission, e.g. edit_site_options. * @param string $capability The capability that allows it regardless of the form. * @param array|null $form The form being submitted. Defaults to the current form. */ function feadmin_has_special_permission( $permission, $capability, $form = null ) { if ( current_user_can( $capability ) ) { return true; } // a logged-out visitor can only hold "Assign Privileged User Roles", used by public registration forms if ( ! is_user_logged_in() && 'assign_roles' !== $permission ) { return false; } if ( null === $form ) { global $fea_form; $form = $fea_form; } // the validation request never runs the permission check, so the rule the // user matches is not known yet: resolve it from the submitted form key if ( ! is_array( $form ) && ! empty( $_POST['_acf_form'] ) ) { static $resolved = array(); $form_key = sanitize_text_field( wp_unslash( $_POST['_acf_form'] ) ); if ( ! isset( $resolved[ $form_key ] ) ) { $form = fea_instance()->form_display->get_form( $form_key ); if ( $form ) { ob_start(); $form = apply_filters( 'frontend_admin/show_form', $form ); ob_end_clean(); } $resolved[ $form_key ] = $form; } $form = $resolved[ $form_key ]; } if ( ! is_array( $form ) || empty( $form['special_permissions'] ) ) { return false; } if ( ! in_array( $permission, (array) $form['special_permissions'], true ) ) { return false; } // A form built inside page content (a block or a page builder widget) is set up // by whoever can edit that page, not necessarily an administrator. Its special // permissions only count when the page's author could do the same themselves, // so an Author cannot hand themselves site options or roles through their own post. foreach ( array( '_elementor_', '_gutenberg_', '_bricks_' ) as $builder ) { if ( false === strpos( (string) ( $form['id'] ?? '' ), $builder ) ) { continue; } $page_id = explode( $builder, (string) $form['id'] )[0]; $author = is_numeric( $page_id ) ? (int) get_post_field( 'post_author', (int) $page_id ) : 0; return $author && user_can( $author, $capability ); } return true; } /** * Random key, kept in a cookie, that ties files uploaded by a logged-out * visitor to that visitor's browser. * * @param bool $create Whether to create the key (and cookie) when there is none. */ function feadmin_get_upload_owner_key( $create = false ) { $key = isset( $_COOKIE['fea_upload_owner'] ) ? sanitize_key( wp_unslash( $_COOKIE['fea_upload_owner'] ) ) : ''; if ( 32 !== strlen( $key ) ) { $key = ''; } if ( ! $key && $create && ! headers_sent() ) { $key = strtolower( wp_generate_password( 32, false ) ); setcookie( 'fea_upload_owner', $key, array( 'expires' => time() + DAY_IN_SECONDS, 'path' => COOKIEPATH ? COOKIEPATH : '/', 'domain' => COOKIE_DOMAIN, 'secure' => is_ssl(), 'httponly' => true, 'samesite' => 'Lax', ) ); $_COOKIE['fea_upload_owner'] = $key; } return $key; } /** * Records who uploaded a file through a form. Logged in uploaders are already * the attachment's author; a logged-out visitor is recorded by their upload key. * * @param int $attachment_id The new attachment. */ function feadmin_mark_upload_owner( $attachment_id ) { if ( is_user_logged_in() ) { return; } $key = feadmin_get_upload_owner_key( true ); if ( $key ) { update_post_meta( $attachment_id, '_fea_upload_owner', wp_hash( $key ) ); } } /** * Whether the current visitor may change an attachment submitted in a form: * its title, caption, description, alt text, file location or metadata. The * submitted value is only an ID, so it must be an attachment the visitor can * edit or uploaded themselves. * * @param mixed $attachment_id The submitted attachment ID. */ function feadmin_can_edit_uploaded_attachment( $attachment_id ) { if ( ! is_numeric( $attachment_id ) ) { return false; } $attachment_id = (int) $attachment_id; if ( $attachment_id <= 0 || 'attachment' !== get_post_type( $attachment_id ) ) { return false; } if ( current_user_can( 'edit_post', $attachment_id ) ) { return true; } $author = (int) get_post_field( 'post_author', $attachment_id ); if ( is_user_logged_in() ) { return $author && get_current_user_id() === $author; } $owner = get_post_meta( $attachment_id, '_fea_upload_owner', true ); $key = feadmin_get_upload_owner_key(); return ! $author && $owner && $key && hash_equals( (string) $owner, wp_hash( $key ) ); } /** * Field types whose values are uploaded files. */ function feadmin_get_upload_field_types() { return apply_filters( 'frontend_admin/upload_field_types', array( 'file', 'image', 'upload_file', 'featured_image', 'main_image', 'site_logo', 'upload_image', 'gallery', 'product_images', 'upload_files', 'site_favicon' ) ); } function feadmin_get_random_string( $length = 15 ) { $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; $charactersLength = strlen( $characters ); $randomString = ''; for ( $i = 0; $i < $length; $i++ ) { $randomString .= $characters[ wp_rand( 0, $charactersLength - 1 ) ]; } return $randomString; } function feadmin_get_client_ip() { $server_ip_keys = array( 'HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR', ); foreach ( $server_ip_keys as $key ) { if ( isset( $_SERVER[ $key ] ) && filter_var( $_SERVER[ $key ], FILTER_VALIDATE_IP ) ) { return esc_html( $_SERVER[ $key ] ); } } // Fallback local ip. return '127.0.0.1'; } function feadmin_get_site_domain() { return str_ireplace( 'www.', '', wp_parse_url( home_url(), PHP_URL_HOST ) ); } function feadmin_duplicate_slug( $prefix = '' ) { static $i; if ( null === $i ) { $i = 2; } else { $i ++; } $new_slug = sprintf( '%s_copy%s', $prefix, $i ); if ( ! feadmin_slug_exists( $new_slug ) ) { return $new_slug; } else { return feadmin_duplicate_slug( $prefix ); } } function feadmin_slug_exists( $post_name ) { global $wpdb; if ( $wpdb->get_row( $wpdb->prepare( "SELECT post_name FROM $wpdb->posts WHERE post_name = %s", $post_name ), 'ARRAY_A' ) ) { return true; } else { return false; } } function feadmin_sanitize_input ( $data = false ) { if( ! $data ) return $data; if( is_array( $data ) ){ return feadmin_sanitize_array( $data ); }else{ return wp_kses_post( $data ); } } function feadmin_sanitize_array ($data = array()) { if (!is_array($data) || !count($data)) { return array(); } foreach ($data as $k => $v) { if (!is_array($v) && !is_object($v)) { //if $k is "to", "cc", or "bcc" get the text between the < and the > if( in_array( $k, [ 'email_to', 'email_to_cc', 'email_to_bcc', 'email_from', 'email_reply_to' ] ) ) { $addresses = explode( ',', $v ); foreach( $addresses as $key => $address ) { $address = trim( $address ); //check if there is "<" if( strpos( $address, '<' ) !== false ){ $address = explode( '<', $address ); $name = $address[0]; $email = $address[1]; $email = sanitize_text_field( $email ); $email = str_replace( '>', '', $email ); if( $name ){ $name = sanitize_text_field( $name ); $address = $name.' <'.$email.'>'; }else{ $address = $email; } }else{ $address = sanitize_text_field( $address ); $address = str_replace( '>', '', $address ); } $addresses[ $key ] = $address; } $v = implode( ', ', $addresses ); }else{ if( ! $v ){ $data[$k] = ''; }else{ $v = wp_kses_post($v); $data[$k] = $v; } } } if (is_array($v)) { $data[$k] = feadmin_sanitize_array($v); } } return $data; } function feadmin_parse_args( $args, $defaults ) { $new_args = (array) $defaults; if ( ! is_array( $args ) ) { return $defaults; } foreach ( $args as $key => $value ) { if ( is_array( $value ) && isset( $new_args[ $key ] ) ) { $new_args[ $key ] = feadmin_parse_args( $value, $new_args[ $key ] ); } else { $new_args[ $key ] = $value; } } return $new_args; } function feadmin_edit_mode() { $edit_mode = false; if ( ! empty( fea_instance()->elementor ) ) { $edit_mode = \Elementor\Plugin::$instance->editor->is_edit_mode(); } if ( ! empty( $GLOBALS['admin_form']['preview_mode'] ) ) { $edit_mode = true; } $current_screen = get_current_screen(); if ( $current_screen instanceof WP_Screen && ! empty( $current_screen->is_block_editor ) ) { $edit_mode = true; } return $edit_mode; } function feadmin_get_product_object() { if ( isset( $GLOBALS['admin_form']['save_to_product'] ) ) { $form = $GLOBALS['admin_form']; if ( $form['save_to_product'] == 'edit_product' ) { return wc_get_product( $form['product_id'] ); } } return false; } function feadmin_get_field_type_groups( $type = 'all' ) { $fields = array(); if ( $type == 'all' ) { $fields['acf'] = array( 'label' => __( 'ACF Field', 'frontend-admin' ), 'options' => array( 'ACF_fields' => __( 'ACF Fields', 'frontend-admin' ), 'ACF_field_groups' => __( 'ACF Field Groups', 'frontend-admin' ), ), ); $fields['layout'] = array( 'label' => __( 'Layout', 'frontend-admin' ), 'options' => array( 'message' => __( 'Message', 'frontend-admin' ), // 'tab' => __( 'Tab', 'frontend-admin' ), ), ); } if ( $type == 'all' || $type == 'post' ) { $fields['post'] = array( 'label' => __( 'Post', 'frontend-admin' ), 'options' => array( 'title' => __( 'Post Title', 'frontend-admin' ), 'slug' => __( 'Slug', 'frontend-admin' ), 'content' => __( 'Post Content', 'frontend-admin' ), 'featured_image' => __( 'Featured Image', 'frontend-admin' ), 'excerpt' => __( 'Post Excerpt', 'frontend-admin' ), 'categories' => __( 'Categories', 'frontend-admin' ), 'tags' => __( 'Tags', 'frontend-admin' ), 'author' => __( 'Post Author', 'frontend-admin' ), 'published_on' => __( 'Published On', 'frontend-admin' ), 'post_type' => __( 'Post Type', 'frontend-admin' ), 'menu_order' => __( 'Menu Order', 'frontend-admin' ), 'allow_comments' => __( 'Allow Comments', 'frontend-admin' ), 'taxonomy' => __( 'Custom Taxonomy', 'frontend-admin' ), ), ); } if ( $type == 'all' || $type == 'user' ) { $fields['user'] = array( 'label' => __( 'User', 'frontend-admin' ), 'options' => array( 'username' => __( 'Username', 'frontend-admin' ), 'password' => __( 'Password', 'frontend-admin' ), 'confirm_password' => __( 'Confirm Password', 'frontend-admin' ), 'email' => __( 'Email', 'frontend-admin' ), 'first_name' => __( 'First Name', 'frontend-admin' ), 'last_name' => __( 'Last Name', 'frontend-admin' ), 'nickname' => __( 'Nickname', 'frontend-admin' ), 'display_name' => __( 'Display Name', 'frontend-admin' ), 'bio' => __( 'Biography', 'frontend-admin' ), 'role' => __( 'Role', 'frontend-admin' ), ), ); } if ( $type == 'all' || $type == 'term' ) { $fields['term'] = array( 'label' => __( 'Term', 'frontend-admin' ), 'options' => array( 'term_name' => __( 'Term Name', 'frontend-admin' ), 'term_slug' => __( 'Term Slug', 'frontend-admin' ), 'term_description' => __( 'Term Description', 'frontend-admin' ), ), ); } $fields = apply_filters( 'frontend_admin/form/elementor/field_select_options', $fields, $type ); return $fields; } /* * get_selected_field * * This function will return the label for a given clone choice * * @type function * @date 17/06/2016 * @since 5.3.8 * * @param $selector (mixed) * @return (string) */ function feadmin_get_selected_field( $selector = '', $type = '' ) { // bail early no selector if ( ! $selector ) { return ''; } if ( is_numeric( $selector ) ) { return get_post_field( 'post_title', $selector ); } // ajax_fields if ( isset( $_POST['fields'][ $selector ] ) ) { $selector = sanitize_text_field( $_POST['fields'][ $selector ] ); return feadmin_field_choice( $selector ); } // field if ( acf_is_field_key( $selector ) ) { return feadmin_field_choice( acf_get_field( $selector ) ); } // group if ( acf_is_field_group_key( $selector ) ) { return feadmin_group_choice( acf_get_field_group( $selector ) ); } if ( feadmin_is_admin_form_key( $selector ) ) { return feadmin_group_choice( fea_instance()->form_display->get_form( $selector ) ); } // return return $selector; } /* * feadmin_field_choice * * This function will return the text for a field choice * * @type function * @date 20/07/2016 * @since 5.4.0 * * @param $field (array) * @return (string) */ function feadmin_field_choice( $field ) { // bail early if no field if ( ! $field ) { return __( 'Unknown field', 'frontend-admin' ); } // title $title = $field['label'] ? $field['label'] : __( '(no title)', 'frontend-admin' ); // append type $title .= ' (' . $field['type'] . ')'; // ancestors // - allow for AJAX to send through ancestors count $ancestors = isset( $field['ancestors'] ) ? $field['ancestors'] : count( acf_get_field_ancestors( $field ) ); $title = str_repeat( '- ', $ancestors ) . $title; // return return $title; } /* * feadmin_group_choice * * This function will return the text for a group choice * * @type function * @date 20/07/2016 * @since 5.4.0 * * @param $field_group (array) * @return (string) */ function feadmin_group_choice( $field_group ) { // bail early if no field group if ( ! $field_group ) { return __( 'Unknown field group', 'frontend-admin' ); } // return return sprintf( /* translators: %s: value */ __( 'All fields from %s', 'frontend-admin' ), $field_group['title'] ); } /* * get_selected_fields * * This function will return an array of choices data for Select2 * * @type function * @date 17/06/2016 * @since 5.3.8 * * @param $value (mixed) * @return (array) */ function feadmin_get_selected_fields( $value, $choices = array() ) { // bail early if no $value if ( empty( $value ) ) { return $choices; } // force value to array $value = acf_get_array( $value ); // loop foreach ( $value as $v ) { $choices[ $v ] = feadmin_get_selected_field( $v ); } // return return $choices; } function feadmin_is_admin_form_key( $id ) { if ( is_string( $id ) && substr( $id, 0, 5 ) === 'form_' ) { return true; } return false; } function feadmin_form_choices( $choices = array() ) { $args = array( 'post_type' => 'admin_form', 'posts_per_page' => '-1', 'post_status' => 'any', ); $forms = get_posts( $args ); if ( empty( $forms ) ) { return $choices; } foreach ( $forms as $form ) { $choices[ $form->ID ] = $form->post_title; } return $choices; } /* * fea_encrypt * * This function will encrypt an array using PHP * https://bhoover.com/using-php-openssl_encrypt-openssl_decrypt-encrypt-decrypt-data/ * * @type function * @date 02/11/22 * @since 3.9.11 * * @param $data (array) * @return (string) */ function fea_encrypt( $data ) { if ( empty( $data ) ) { return false; } $data = json_encode( $data ); // bail early if no encrypt function if ( ! function_exists( 'openssl_encrypt' ) ) { wp_die( 'Please enable the openssl extension in your PHP configuration to use the encryption feature.' ); } // generate a key $key = wp_hash( 'fea_encrypt' ); // Generate an initialization vector $iv = openssl_random_pseudo_bytes( openssl_cipher_iv_length( 'aes-256-cbc' ) ); // Encrypt the data using AES 256 encryption in CBC mode using our encryption key and initialization vector. $encrypted_data = openssl_encrypt( $data, 'aes-256-cbc', $key, 0, $iv ); // The $iv is just as important as the key for decrypting, so save it with our encrypted data using a unique separator (::) return base64_encode( $encrypted_data . '::' . $iv ); } /* * fea_decrypt * * This function will decrypt an encrypted string using PHP * https://bhoover.com/using-php-openssl_encrypt-openssl_decrypt-encrypt-decrypt-data/ * * @type function * @date 02/11/22 * @since 3.9.11 * * @param $data (string) * @return (array) */ function fea_decrypt( $data = '' ) { if ( empty( $data ) ) { return false; } // bail early if no decrypt function if ( ! function_exists( 'openssl_decrypt' ) ) { wp_die( 'Please enable the openssl extension in your PHP configuration to use the encryption feature.' ); } // generate a key $key = wp_hash( 'fea_encrypt' ); // To decrypt, split the encrypted data from our IV - our unique separator used was "::" list($encrypted_data, $iv) = explode( '::', base64_decode( $data ), 2 ); // decrypt $data = openssl_decrypt( $encrypted_data, 'aes-256-cbc', $key, 0, $iv ); return json_decode( $data, true ); } /** * feadmin_get_time_input * * Returns the HTML of a text input. * * @date 3/02/2014 * @since 5.0.0 * * @param array $attrs The array of attrs. * @return string */ function feadmin_get_time_input( $attrs = array() ) { $attrs = wp_parse_args( $attrs, array( 'type' => 'time', ) ); if ( isset( $attrs['value'] ) && is_string( $attrs['value'] ) ) { $attrs['value'] = htmlspecialchars( $attrs['value'] ); } return sprintf( '', feadmin_get_esc_attrs( $attrs ) ); } /* * feadmin_verify_nonce * * This function will look at the $_POST['_acf_nonce'] value and return true or false * * @type function * @date 15/10/13 * @since 3.12 * * @param $nonce (string) * @return (boolean) */ function feadmin_verify_nonce( $value ) { // vars $nonce = acf_maybe_get_POST( '_acf_nonce' ); // bail early nonce does not match (post|user|comment|term) if ( ! $nonce || ! wp_verify_nonce( $nonce, $value ) ) { return false; } // reset nonce (only allow 1 save) $_POST['_acf_nonce'] = false; // return return true; } /* * feadmin_verify_ajax * * This function will return true if the current AJAX request is valid * It's action will also allow WPML to set the lang and avoid AJAX get_posts issues * * @type function * @date 7/08/2015 * @since 5.2.3 * * @param n/a * @return (boolean) */ /** * Returns true if the current AJAX request is valid. * It's action will also allow WPML to set the lang and avoid AJAX get_posts issues * * @since 5.2.3 * * @param string $nonce The nonce to check. * @param string $action The action of the nonce. * @return boolean */ function feadmin_verify_ajax( $nonce = '', $action = '' ) { // Bail early if we don't have a nonce to check. if ( empty( $nonce ) && empty( $_REQUEST['nonce'] ) ) { return false; } $nonce_to_check = ! empty( $nonce ) ? $nonce : $_REQUEST['nonce']; // phpcs:ignore WordPress.Security -- We're verifying a nonce here. $nonce_action = ! empty( $action ) ? $action : 'acf_nonce'; // Bail if nonce can't be verified. if ( ! wp_verify_nonce( sanitize_text_field( $nonce_to_check ), $nonce_action ) ) { return false; } // Action for 3rd party customization (WPML). do_action( 'acf/verify_ajax' ); return true; } /** * feadmin_get_esc_attrs * * Generated valid HTML from an array of attrs. * * @date 11/6/19 * @since 5.8.1 * * @param array $attrs The array of attrs. * @return string */ function feadmin_get_esc_attrs( $attrs ) { $html = ''; // Loop over attrs and validate data types. foreach ( $attrs as $k => $v ) { // String (but don't trim value). if ( is_string( $v ) && ( $k !== 'value' ) ) { $v = trim( $v ); // Boolean } elseif ( is_bool( $v ) ) { $v = $v ? 1 : 0; // Object } elseif ( is_array( $v ) || is_object( $v ) ) { $v = json_encode( $v ); } // Generate HTML. $html .= sprintf( ' %s="%s"', esc_attr( $k ), esc_attr( $v ) ); } // Return trimmed. return trim( $html ); } /* * feadmin_encode_choices * * description * * @type function * @date 4/06/2014 * @since 5.0.0 * * @param $post_id (int) * @return $post_id (int) */ function feadmin_encode_choices( $array = array(), $show_keys = true ) { // bail early if not array (maybe a single string) if ( ! is_array( $array ) ) { return $array; } // bail early if empty array if ( empty( $array ) ) { return ''; } // vars $string = ''; // if allowed to show keys (good for choices, not for default values) if ( $show_keys ) { // loop foreach ( $array as $k => $v ) { // ignore if key and value are the same if ( strval( $k ) == strval( $v ) ) { continue; } // show key in the value $array[ $k ] = $k . ' : ' . $v; } } // implode $string = implode( "\n", $array ); // return return $string; } function feadmin_decode_choices( $string = '', $array_keys = false ) { // bail early if already array if ( is_array( $string ) ) { return $string; // allow numeric values (same as string) } elseif ( is_numeric( $string ) ) { // do nothing // bail early if not a string } elseif ( ! is_string( $string ) ) { return array(); // bail early if is empty string } elseif ( $string === '' ) { return array(); } // vars $array = array(); // explode $lines = explode( "\n", $string ); // key => value foreach ( $lines as $line ) { // vars $k = trim( $line ); $v = trim( $line ); // look for ' : ' if ( feadmin_str_exists( ' : ', $line ) ) { $line = explode( ' : ', $line ); $k = trim( $line[0] ); $v = trim( $line[1] ); } // append $array[ $k ] = $v; } // return only array keys? (good for checkbox default_value) if ( $array_keys ) { return array_keys( $array ); } // return return $array; } /** * feadmin_maybe_get * * This function will return a var if it exists in an array or a default if set * * @since 5.1.5 * * @param $array (array) the array to look within * @param $key (key) the array key to look for. Nested values may be found using '/' * @param $default (mixed) the value returned if not found * @return $value | $default (mixed) */ function feadmin_maybe_get( $array = array(), $key = 0, $default = null ) { return isset( $array[ $key ] ) ? $array[ $key ] : $default; } function feadmin_get_currencies(){ if ( function_exists( 'get_woocommerce_currencies' ) ) { return get_woocommerce_currencies(); } if ( class_exists( 'Easy_Digital_Downloads' ) ) { return edd_get_currencies(); } return [ 'AFN' => 'Afghan Afghani', 'ALL' => 'Albanian Lek', 'DZD' => 'Algerian Dinar', 'AOA' => 'Angolan Kwanza', 'ARS' => 'Argentine Peso', 'AMD' => 'Armenian Dram', 'AWG' => 'Aruban Florin', 'AUD' => 'Australian Dollar', 'AZN' => 'Azerbaijani Manat', 'BSD' => 'Bahamian Dollar', 'BDT' => 'Bangladeshi Taka', 'BBD' => 'Barbadian Dollar', 'BZD' => 'Belize Dollar', 'BMD' => 'Bermudian Dollar', 'BOB' => 'Bolivian Boliviano', 'BAM' => 'Bosnia & Herzegovina Convertible Mark', 'BWP' => 'Botswana Pula', 'BRL' => 'Brazilian Real', 'GBP' => 'British Pound', 'BND' => 'Brunei Dollar', 'BGN' => 'Bulgarian Lev', 'BIF' => 'Burundian Franc', 'KHR' => 'Cambodian Riel', 'CAD' => 'Canadian Dollar', 'CVE' => 'Cape Verdean Escudo', 'KYD' => 'Cayman Islands Dollar', 'XAF' => 'Central African Cfa Franc', 'XPF' => 'Cfp Franc', 'CLP' => 'Chilean Peso', 'CNY' => 'Chinese Renminbi Yuan', 'COP' => 'Colombian Peso', 'KMF' => 'Comorian Franc', 'CDF' => 'Congolese Franc', 'CRC' => 'Costa Rican Colón', 'HRK' => 'Croatian Kuna', 'CZK' => 'Czech Koruna', 'DKK' => 'Danish Krone', 'DJF' => 'Djiboutian Franc', 'DOP' => 'Dominican Peso', 'XCD' => 'East Caribbean Dollar', 'EGP' => 'Egyptian Pound', 'ETB' => 'Ethiopian Birr', 'EUR' => 'Euro', 'FKP' => 'Falkland Islands Pound', 'FJD' => 'Fijian Dollar', 'GMD' => 'Gambian Dalasi', 'GEL' => 'Georgian Lari', 'GIP' => 'Gibraltar Pound', 'GTQ' => 'Guatemalan Quetzal', 'GNF' => 'Guinean Franc', 'GYD' => 'Guyanese Dollar', 'HTG' => 'Haitian Gourde', 'HNL' => 'Honduran Lempira', 'HKD' => 'Hong Kong Dollar', 'HUF' => 'Hungarian Forint', 'ISK' => 'Icelandic Króna', 'INR' => 'Indian Rupee', 'IDR' => 'Indonesian Rupiah', 'ILS' => 'Israeli New Sheqel', 'JMD' => 'Jamaican Dollar', 'JPY' => 'Japanese Yen', 'KZT' => 'Kazakhstani Tenge', 'KES' => 'Kenyan Shilling', 'KGS' => 'Kyrgyzstani Som', 'LAK' => 'Lao Kip', 'LBP' => 'Lebanese Pound', 'LSL' => 'Lesotho Loti', 'LRD' => 'Liberian Dollar', 'MOP' => 'Macanese Pataca', 'MKD' => 'Macedonian Denar', 'MGA' => 'Malagasy Ariary', 'MWK' => 'Malawian Kwacha', 'MYR' => 'Malaysian Ringgit', 'MVR' => 'Maldivian Rufiyaa', 'MRO' => 'Mauritanian Ouguiya', 'MUR' => 'Mauritian Rupee', 'MXN' => 'Mexican Peso', 'MDL' => 'Moldovan Leu', 'MNT' => 'Mongolian Tögrög', 'MAD' => 'Moroccan Dirham', 'MZN' => 'Mozambican Metical', 'MMK' => 'Myanmar Kyat', 'NAD' => 'Namibian Dollar', 'NPR' => 'Nepalese Rupee', 'ANG' => 'Netherlands Antillean Gulden', 'TWD' => 'New Taiwan Dollar', 'NZD' => 'New Zealand Dollar', 'NIO' => 'Nicaraguan Córdoba', 'NGN' => 'Nigerian Naira', 'NOK' => 'Norwegian Krone', 'PKR' => 'Pakistani Rupee', 'PAB' => 'Panamanian Balboa', 'PGK' => 'Papua New Guinean Kina', 'PYG' => 'Paraguayan Guaraní', 'PEN' => 'Peruvian Nuevo Sol', 'PHP' => 'Philippine Peso', 'PLN' => 'Polish Złoty', 'QAR' => 'Qatari Riyal', 'RON' => 'Romanian Leu', 'RUB' => 'Russian Ruble', 'RWF' => 'Rwandan Franc', 'STD' => 'São Tomé and Príncipe Dobra', 'SHP' => 'Saint Helenian Pound', 'SVC' => 'Salvadoran Colón', 'WST' => 'Samoan Tala', 'SAR' => 'Saudi Riyal', 'RSD' => 'Serbian Dinar', 'SCR' => 'Seychellois Rupee', 'SLL' => 'Sierra Leonean Leone', 'SGD' => 'Singapore Dollar', 'SBD' => 'Solomon Islands Dollar', 'SOS' => 'Somali Shilling', 'ZAR' => 'South African Rand', 'KRW' => 'South Korean Won', 'LKR' => 'Sri Lankan Rupee', 'SRD' => 'Surinamese Dollar', 'SZL' => 'Swazi Lilangeni', 'SEK' => 'Swedish Krona', 'CHF' => 'Swiss Franc', 'TJS' => 'Tajikistani Somoni', 'TZS' => 'Tanzanian Shilling', 'THB' => 'Thai Baht', 'TOP' => 'Tongan Paʻanga', 'TTD' => 'Trinidad and Tobago Dollar', 'TRY' => 'Turkish Lira', 'UGX' => 'Ugandan Shilling', 'UAH' => 'Ukrainian Hryvnia', 'AED' => 'United Arab Emirates Dirham', 'USD' => 'United States Dollar', 'UYU' => 'Uruguayan Peso', 'UZS' => 'Uzbekistani Som', 'VUV' => 'Vanuatu Vatu', 'VND' => 'Vietnamese Đồng', 'XOF' => 'West African Cfa Franc', 'YER' => 'Yemeni Rial', 'ZMW' => 'Zambian Kwacha' ]; }