get_setting() * * @type function * @date 28/09/13 * @since 5.0.0 * * @param n/a * @return n/a */ function acf_get_setting( $name, $value = null ) { return acf()->get_setting( $name, $value ); } /* * acf_update_setting * * alias of acf()->update_setting() * * @type function * @date 28/09/13 * @since 5.0.0 * * @param $name (string) * @param $value (mixed) * @return n/a */ function acf_update_setting( $name, $value ) { return acf()->update_setting( $name, $value ); } /* * acf_append_setting * * This function will add a value into the settings array found in the acf object * * @type function * @date 28/09/13 * @since 5.0.0 * * @param $name (string) * @param $value (mixed) * @return n/a */ function acf_append_setting( $name, $value ) { // vars $setting = acf_get_setting( $name, array() ); // bail ealry if not array if( !is_array($setting) ) return false; // append $setting[] = $value; // update acf_update_setting( $name, $setting ); // return return true; } /* * acf_get_compatibility * * This function will return true or false for a given compatibility setting * * @type function * @date 20/01/2015 * @since 5.1.5 * * @param $name (string) * @return (boolean) */ function acf_get_compatibility( $name ) { return apply_filters( "acf/compatibility/{$name}", false ); } /* * acf_has_done * * This function will return true if this action has already been done * * @type function * @date 16/12/2015 * @since 5.3.2 * * @param $name (string) * @return (boolean) */ function acf_has_done( $name ) { // vars $setting = "_has_done_{$name}"; // return true if already done if( acf_get_setting($setting) ) return true; // update setting acf_update_setting($setting, true); // return return false; } /* * acf_get_path * * This function will return the path to a file within the ACF plugin folder * * @type function * @date 28/09/13 * @since 5.0.0 * * @param $path (string) the relative path from the root of the ACF plugin folder * @return (string) */ function acf_get_path( $path ) { return acf_get_setting('path') . $path; } /* * acf_get_dir * * This function will return the url to a file within the ACF plugin folder * * @type function * @date 28/09/13 * @since 5.0.0 * * @param $path (string) the relative path from the root of the ACF plugin folder * @return (string) */ function acf_get_dir( $path ) { return acf_get_setting('dir') . $path; } /* * acf_include * * This function will include a file * * @type function * @date 10/03/2014 * @since 5.0.0 * * @param $post_id (int) * @return $post_id (int) */ function acf_include( $file ) { $path = acf_get_path( $file ); if( file_exists($path) ) { include_once( $path ); } } /* * acf_parse_args * * This function will merge together 2 arrays and also convert any numeric values to ints * * @type function * @date 18/10/13 * @since 5.0.0 * * @param $args (array) * @param $defaults (array) * @return $args (array) */ function acf_parse_args( $args, $defaults = array() ) { // parse args $args = wp_parse_args( $args, $defaults ); // parse types $args = acf_parse_types( $args ); // return return $args; } /* * acf_parse_types * * This function will convert any numeric values to int and trim strings * * @type function * @date 18/10/13 * @since 5.0.0 * * @param $var (mixed) * @return $var (mixed) */ function acf_parse_types( $array ) { // return return array_map( 'acf_parse_type', $array ); } /* * acf_parse_type * * description * * @type function * @date 11/11/2014 * @since 5.0.9 * * @param $post_id (int) * @return $post_id (int) */ function acf_parse_type( $v ) { // bail early if not string if( !is_string($v) ) return $v; // trim $v = trim($v); // convert int (string) to int if( is_numeric($v) && strval((int)$v) === $v ) { $v = intval( $v ); } // return return $v; } /* * acf_get_view * * This function will load in a file from the 'admin/views' folder and allow variables to be passed through * * @type function * @date 28/09/13 * @since 5.0.0 * * @param $view_name (string) * @param $args (array) * @return n/a */ function acf_get_view( $view_name = '', $args = array() ) { // vars $path = acf_get_path("admin/views/{$view_name}.php"); if( file_exists($path) ) { include( $path ); } } /* * acf_merge_atts * * description * * @type function * @date 2/11/2014 * @since 5.0.9 * * @param $post_id (int) * @return $post_id (int) */ function acf_merge_atts( $atts, $extra = array() ) { // bail ealry if no $extra if( empty($extra) ) { return $atts; } // merge in new atts foreach( $extra as $k => $v ) { if( $k == 'class' || $k == 'style' ) { if( $v === '' ) { continue; } $v = $atts[ $k ] . ' ' . $v; } $atts[ $k ] = $v; } // return return $atts; } /* * acf_esc_attr * * This function will return a render of an array of attributes to be used in markup * * @type function * @date 1/10/13 * @since 5.0.0 * * @param $atts (array) * @return n/a */ function acf_esc_attr( $atts ) { // is string? if( is_string($atts) ) { $atts = trim( $atts ); return esc_attr( $atts ); } // validate if( empty($atts) ) { return ''; } // vars $e = array(); // loop through and render foreach( $atts as $k => $v ) { // object if( is_array($v) || is_object($v) ) { $v = json_encode($v); // boolean } elseif( is_bool($v) ) { $v = $v ? 1 : 0; // string } elseif( is_string($v) ) { $v = trim($v); } // append $e[] = $k . '="' . esc_attr( $v ) . '"'; } // echo return implode(' ', $e); } function acf_esc_attr_e( $atts ) { echo acf_esc_attr( $atts ); } /* * acf_hidden_input * * description * * @type function * @date 3/02/2014 * @since 5.0.0 * * @param $post_id (int) * @return $post_id (int) */ function acf_get_hidden_input( $atts ) { $atts['type'] = 'hidden'; return ''; } function acf_hidden_input( $atts ) { echo acf_get_hidden_input( $atts ); } /* * acf_extract_var * * This function will remove the var from the array, and return the var * * @type function * @date 2/10/13 * @since 5.0.0 * * @param $array (array) * @param $key (string) * @return (mixed) */ function acf_extract_var( &$array, $key, $default = null ) { // check if exists if( is_array($array) && array_key_exists($key, $array) ) { // store value $v = $array[ $key ]; // unset unset( $array[ $key ] ); // return return $v; } // return return $default; } /* * acf_extract_vars * * This function will remove the vars from the array, and return the vars * * @type function * @date 8/10/13 * @since 5.0.0 * * @param $post_id (int) * @return $post_id (int) */ function acf_extract_vars( &$array, $keys ) { $r = array(); foreach( $keys as $key ) { $r[ $key ] = acf_extract_var( $array, $key ); } return $r; } /* * acf_get_sub_array * * This function will return a sub array of data * * @type function * @date 15/03/2016 * @since 5.3.2 * * @param $post_id (int) * @return $post_id (int) */ function acf_get_sub_array( $array, $keys ) { $r = array(); foreach( $keys as $key ) { $r[ $key ] = $array[ $key ]; } return $r; } /* * acf_get_post_types * * This function will return an array of available post types * * @type function * @date 7/10/13 * @since 5.0.0 * * @param $exclude (array) * @param $include (array) * @return (array) */ function acf_get_post_types( $exclude = array(), $include = array() ) { // get all custom post types $post_types = get_post_types(); // core exclude $exclude = wp_parse_args( $exclude, array('acf-field', 'acf-field-group', 'revision', 'nav_menu_item') ); // include if( !empty($include) ) { foreach( array_keys($include) as $i ) { $post_type = $include[ $i ]; if( post_type_exists($post_type) ) { $post_types[ $post_type ] = $post_type; } } } // exclude foreach( array_values($exclude) as $i ) { unset( $post_types[ $i ] ); } // simplify keys $post_types = array_values($post_types); // return return $post_types; } function acf_get_pretty_post_types( $post_types = array() ) { // get post types if( empty($post_types) ) { // get all custom post types $post_types = acf_get_post_types(); } // get labels $ref = array(); $r = array(); foreach( $post_types as $post_type ) { // vars $label = acf_get_post_type_label($post_type); // append to r $r[ $post_type ] = $label; // increase counter if( !isset($ref[ $label ]) ) { $ref[ $label ] = 0; } $ref[ $label ]++; } // get slugs foreach( array_keys($r) as $i ) { // vars $post_type = $r[ $i ]; if( $ref[ $post_type ] > 1 ) { $r[ $i ] .= ' (' . $i . ')'; } } // return return $r; } /* * acf_get_post_type_label * * This function will return a pretty label for a specific post_type * * @type function * @date 5/07/2016 * @since 5.4.0 * * @param $post_type (string) * @return (string) */ function acf_get_post_type_label( $post_type ) { // vars $label = $post_type; // check that object exists // - case exists when importing field group from another install and post type does not exist if( post_type_exists($post_type) ) { $obj = get_post_type_object($post_type); $label = $obj->labels->singular_name; } // return return $label; } /* * acf_verify_nonce * * This function will look at the $_POST['_acfnonce'] value and return true or false * * @type function * @date 15/10/13 * @since 5.0.0 * * @param $nonce (string) * @return (boolean) */ function acf_verify_nonce( $value, $post_id = 0 ) { // vars $nonce = acf_maybe_get( $_POST, '_acfnonce' ); // bail early nonce does not match (post|user|comment|term) if( !$nonce || !wp_verify_nonce($nonce, $value) ) return false; // if saving specific post if( $post_id ) { // vars $form_post_id = (int) acf_maybe_get( $_POST, 'post_ID' ); $post_parent = wp_is_post_revision( $post_id ); // 1. no $_POST['post_id'] (shopp plugin) if( !$form_post_id ) { // do nothing (don't remove this if statement!) // 2. direct match (this is the post we were editing) } elseif( $post_id === $form_post_id ) { // do nothing (don't remove this if statement!) // 3. revision (this is an preview autosave) } elseif( $post_parent === $form_post_id ) { // do nothing (don't remove this if statement!) // 4. no match (this post is a custom created one during the save proccess via either WP or 3rd party) } else { // return false early and prevent $_POST['_acfnonce'] from being reset // this will allow another save_post to save the real post return false; } } // reset nonce (only allow 1 save) $_POST['_acfnonce'] = false; // return return true; } /* * acf_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) */ function acf_verify_ajax() { // bail early if not acf action if( empty($_POST['action']) || substr($_POST['action'], 0, 3) !== 'acf' ) { return false; } // bail early if not acf nonce if( empty($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'acf_nonce') ) { return false; } // action for 3rd party customization do_action('acf/verify_ajax'); // return return true; } /* * acf_add_admin_notice * * This function will add the notice data to a setting in the acf object for the admin_notices action to use * * @type function * @date 17/10/13 * @since 5.0.0 * * @param $text (string) * @param $class (string) * @return (int) message ID (array position) */ function acf_add_admin_notice( $text, $class = '', $wrap = 'p' ) { // vars $admin_notices = acf_get_admin_notices(); // add to array $admin_notices[] = array( 'text' => $text, 'class' => "updated {$class}", 'wrap' => $wrap ); // update acf_update_setting( 'admin_notices', $admin_notices ); // return return ( count( $admin_notices ) - 1 ); } /* * acf_get_admin_notices * * This function will return an array containing any admin notices * * @type function * @date 17/10/13 * @since 5.0.0 * * @param n/a * @return (array) */ function acf_get_admin_notices() { // vars $admin_notices = acf_get_setting( 'admin_notices' ); // validate if( !$admin_notices ) { $admin_notices = array(); } // return return $admin_notices; } /* * acf_get_image_sizes * * This function will return an array of available image sizes * * @type function * @date 23/10/13 * @since 5.0.0 * * @param n/a * @return (array) */ function acf_get_image_sizes() { // vars $sizes = array( 'thumbnail' => __("Thumbnail",'acf'), 'medium' => __("Medium",'acf'), 'large' => __("Large",'acf') ); // find all sizes $all_sizes = get_intermediate_image_sizes(); // add extra registered sizes if( !empty($all_sizes) ) { foreach( $all_sizes as $size ) { // bail early if already in array if( isset($sizes[ $size ]) ) { continue; } // append to array $label = str_replace('-', ' ', $size); $label = ucwords( $label ); $sizes[ $size ] = $label; } } // add sizes foreach( array_keys($sizes) as $s ) { // vars $data = acf_get_image_size($s); // append if( $data['width'] && $data['height'] ) { $sizes[ $s ] .= ' (' . $data['width'] . ' x ' . $data['height'] . ')'; } } // add full end $sizes['full'] = __("Full Size",'acf'); // filter for 3rd party customization $sizes = apply_filters( 'acf/get_image_sizes', $sizes ); // return return $sizes; } function acf_get_image_size( $s = '' ) { // global global $_wp_additional_image_sizes; // rename for nicer code $_sizes = $_wp_additional_image_sizes; // vars $data = array( 'width' => isset($_sizes[$s]['width']) ? $_sizes[$s]['width'] : get_option("{$s}_size_w"), 'height' => isset($_sizes[$s]['height']) ? $_sizes[$s]['height'] : get_option("{$s}_size_h") ); // return return $data; } /* * acf_get_terms * * This function is a wrapper for the get_terms() function * * @type function * @date 28/09/2016 * @since 5.4.0 * * @param $args (array) * @return (array) */ function acf_get_terms( $args ) { // global global $wp_version; // vars $terms = array(); // WP 4.5+ if( version_compare($wp_version, '4.5', '>=' ) ) { $terms = get_terms( $args ); // WP < 4.5 } else { $terms = get_terms( $args['taxonomy'], $args ); } // return return $terms; } /* * acf_get_taxonomies * * This function will return an array of available taxonomies * * @type function * @date 7/10/13 * @since 5.0.0 * * @param n/a * @return (array) */ function acf_get_taxonomies() { // get all taxonomies $taxonomies = get_taxonomies( false, 'objects' ); $ignore = array( 'nav_menu', 'link_category' ); $r = array(); // populate $r foreach( $taxonomies as $taxonomy ) { if( in_array($taxonomy->name, $ignore) ) { continue; } $r[ $taxonomy->name ] = $taxonomy->name; //"{$taxonomy->labels->singular_name}"; // ({$taxonomy->name}) } // return return $r; } function acf_get_pretty_taxonomies( $taxonomies = array() ) { // get post types if( empty($taxonomies) ) { // get all custom post types $taxonomies = acf_get_taxonomies(); } // get labels $ref = array(); $r = array(); foreach( array_keys($taxonomies) as $i ) { // vars $taxonomy = acf_extract_var( $taxonomies, $i); $obj = get_taxonomy( $taxonomy ); $name = $obj->labels->singular_name; // append to r $r[ $taxonomy ] = $name; // increase counter if( !isset($ref[ $name ]) ) { $ref[ $name ] = 0; } $ref[ $name ]++; } // get slugs foreach( array_keys($r) as $i ) { // vars $taxonomy = $r[ $i ]; if( $ref[ $taxonomy ] > 1 ) { $r[ $i ] .= ' (' . $i . ')'; } } // return return $r; } /* * acf_get_taxonomy_terms * * This function will return an array of available taxonomy terms * * @type function * @date 7/10/13 * @since 5.0.0 * * @param $taxonomies (array) * @return (array) */ function acf_get_taxonomy_terms( $taxonomies = array() ) { // force array $taxonomies = acf_get_array( $taxonomies ); // get pretty taxonomy names $taxonomies = acf_get_pretty_taxonomies( $taxonomies ); // vars $r = array(); // populate $r foreach( array_keys($taxonomies) as $taxonomy ) { // vars $label = $taxonomies[ $taxonomy ]; $is_hierarchical = is_taxonomy_hierarchical( $taxonomy ); $terms = acf_get_terms(array( 'taxonomy' => $taxonomy, 'hide_empty' => false )); // bail early i no terms if( empty($terms) ) continue; // sort into hierachial order! if( $is_hierarchical ) { $terms = _get_term_children( 0, $terms, $taxonomy ); } // add placeholder $r[ $label ] = array(); // add choices foreach( $terms as $term ) { $k = "{$taxonomy}:{$term->slug}"; $r[ $label ][ $k ] = acf_get_term_title( $term ); } } // return return $r; } function acf_get_term_title( $term ) { // title $title = $term->name; // empty if( $title === '' ) { $title = __('(no title)', 'acf'); } // ancestors if( is_taxonomy_hierarchical($term->taxonomy) ) { $ancestors = get_ancestors( $term->term_id, $term->taxonomy ); $title = str_repeat('- ', count($ancestors)) . $title; } // return return $title; } /* * acf_decode_taxonomy_terms * * This function decodes the $taxonomy:$term strings into a nested array * * @type function * @date 27/02/2014 * @since 5.0.0 * * @param $terms (array) * @return (array) */ function acf_decode_taxonomy_terms( $strings = false ) { // bail early if no terms if( empty($strings) ) return false; // vars $terms = array(); // loop foreach( $strings as $string ) { // vars $data = acf_decode_taxonomy_term( $string ); $taxonomy = $data['taxonomy']; $term = $data['term']; // create empty array if( !isset($terms[ $taxonomy ]) ) { $terms[ $taxonomy ] = array(); } // append $terms[ $taxonomy ][] = $term; } // return return $terms; } /* * acf_decode_taxonomy_term * * This function will convert a term string into an array of term data * * @type function * @date 31/03/2014 * @since 5.0.0 * * @param $string (string) * @return (array) */ function acf_decode_taxonomy_term( $string ) { // vars $r = array(); // vars $data = explode(':', $string); $taxonomy = 'category'; $term = ''; // check data if( isset($data[1]) ) { $taxonomy = $data[0]; $term = $data[1]; } // add data to $r $r['taxonomy'] = $taxonomy; $r['term'] = $term; // return return $r; } /* * acf_get_array * * This function will force a variable to become an array * * @type function * @date 4/02/2014 * @since 5.0.0 * * @param $var (mixed) * @return (array) */ function acf_get_array( $var = false, $delimiter = ',' ) { // is array? if( is_array($var) ) { return $var; } // bail early if empty if( empty($var) && !is_numeric($var) ) { return array(); } // string if( is_string($var) && $delimiter ) { return explode($delimiter, $var); } // place in array return array( $var ); } /* * acf_get_numeric * * This function will return numeric values * * @type function * @date 15/07/2016 * @since 5.4.0 * * @param $value (mixed) * @return (mixed) */ function acf_get_numeric( $value = '' ) { // vars $numbers = array(); $is_array = is_array($value); // loop foreach( (array) $value as $v ) { if( is_numeric($v) ) $numbers[] = (int) $v; } // bail early if is empty if( empty($numbers) ) return false; // convert array if( !$is_array ) $numbers = $numbers[0]; // return return $numbers; } /* * acf_get_posts * * This function will return an array of posts making sure the order is correct * * @type function * @date 3/03/2015 * @since 5.1.5 * * @param $args (array) * @return (array) */ function acf_get_posts( $args = array() ) { // vars $posts = array(); // defaults // leave suppress_filters as true becuase we don't want any plugins to modify the query as we know exactly what $args = wp_parse_args( $args, array( 'posts_per_page' => -1, 'post_type' => '', 'post_status' => 'any' )); // post type if( empty($args['post_type']) ) { $args['post_type'] = acf_get_post_types(); } // validate post__in if( $args['post__in'] ) { // force value to array $args['post__in'] = acf_get_array( $args['post__in'] ); // convert to int $args['post__in'] = array_map('intval', $args['post__in']); // add filter to remove post_type // use 'query' filter so that 'suppress_filters' can remain true //add_filter('query', '_acf_query_remove_post_type'); // order by post__in $args['orderby'] = 'post__in'; } // load posts in 1 query to save multiple DB calls from following code $posts = get_posts($args); // remove this filter (only once) //remove_filter('query', '_acf_query_remove_post_type'); // validate order if( $posts && $args['post__in'] ) { // vars $order = array(); // generate sort order foreach( $posts as $i => $post ) { $order[ $i ] = array_search($post->ID, $args['post__in']); } // sort array_multisort($order, $posts); } // return return $posts; } /* * _acf_query_remove_post_type * * This function will remove the 'wp_posts.post_type' WHERE clause completely * When using 'post__in', this clause is unneccessary and slow. * * @type function * @date 4/03/2015 * @since 5.1.5 * * @param $sql (string) * @return $sql */ function _acf_query_remove_post_type( $sql ) { // global global $wpdb; // bail ealry if no 'wp_posts.ID IN' if( strpos($sql, "$wpdb->posts.ID IN") === false ) { return $sql; } // get bits $glue = 'AND'; $bits = explode($glue, $sql); // loop through $where and remove any post_type queries foreach( $bits as $i => $bit ) { if( strpos($bit, "$wpdb->posts.post_type") !== false ) { unset( $bits[ $i ] ); } } // join $where back together $sql = implode($glue, $bits); // return return $sql; } /* * acf_get_grouped_posts * * This function will return all posts grouped by post_type * This is handy for select settings * * @type function * @date 27/02/2014 * @since 5.0.0 * * @param $args (array) * @return (array) */ function acf_get_grouped_posts( $args ) { // vars $r = array(); // defaults $args = wp_parse_args( $args, array( 'posts_per_page' => -1, 'paged' => 0, 'post_type' => 'post', 'orderby' => 'menu_order title', 'order' => 'ASC', 'post_status' => 'any', 'suppress_filters' => false, 'update_post_meta_cache' => false, )); // find array of post_type $post_types = acf_get_array( $args['post_type'] ); $post_types_labels = acf_get_pretty_post_types($post_types); // attachment doesn't work if it is the only item in an array if( count($post_types) == 1 ) { $args['post_type'] = current($post_types); } // add filter to orderby post type add_filter('posts_orderby', '_acf_orderby_post_type', 10, 2); // get posts $posts = get_posts( $args ); // remove this filter (only once) remove_filter('posts_orderby', '_acf_orderby_post_type'); // loop foreach( $post_types as $post_type ) { // vars $this_posts = array(); $this_group = array(); // populate $this_posts foreach( array_keys($posts) as $key ) { if( $posts[ $key ]->post_type == $post_type ) { $this_posts[] = acf_extract_var( $posts, $key ); } } // bail early if no posts for this post type if( empty($this_posts) ) continue; // sort into hierachial order! // this will fail if a search has taken place because parents wont exist if( is_post_type_hierarchical($post_type) && empty($args['s'])) { // vars $match_id = $this_posts[ 0 ]->ID; $offset = 0; $length = count($this_posts); $parent = acf_maybe_get( $args, 'post_parent', 0 ); // get all posts $all_args = array_merge($args, array( 'posts_per_page' => -1, 'paged' => 0, 'post_type' => $post_type )); $all_posts = get_posts( $all_args ); // loop over posts and update $offset foreach( $all_posts as $offset => $p ) { if( $p->ID == $match_id ) break; } // order posts $ordered_posts = get_page_children( $parent, $all_posts ); // if has ordered posts if( !empty($ordered_posts) ) { // reset $this_posts $this_posts = array(); // append for( $i = $offset; $i < ($offset + $length); $i++ ) { $this_posts[] = acf_extract_var( $ordered_posts, $i ); } // clean up null values $this_posts = array_filter($this_posts); } } // populate $this_posts foreach( array_keys($this_posts) as $key ) { // extract post $post = acf_extract_var( $this_posts, $key ); // add to group $this_group[ $post->ID ] = $post; } // group by post type $post_type_name = $post_types_labels[ $post_type ]; $r[ $post_type_name ] = $this_group; } // return return $r; } function _acf_orderby_post_type( $ordeby, $wp_query ) { // global global $wpdb; // get post types $post_types = $wp_query->get('post_type'); // prepend SQL if( is_array($post_types) ) { $post_types = implode("','", $post_types); $ordeby = "FIELD({$wpdb->posts}.post_type,'$post_types')," . $ordeby; } // return return $ordeby; } function acf_get_post_title( $post = 0, $is_search = false ) { // vars $post = get_post($post); $title = ''; $prepend = ''; $append = ''; // bail early if no post if( !$post ) return ''; // title $title = get_the_title( $post->ID ); // empty if( $title === '' ) { $title = __('(no title)', 'acf'); } // status if( get_post_status( $post->ID ) != "publish" ) { $append .= ' (' . get_post_status( $post->ID ) . ')'; } // ancestors if( $post->post_type !== 'attachment' ) { // get ancestors $ancestors = get_ancestors( $post->ID, $post->post_type ); $prepend .= str_repeat('- ', count($ancestors)); // add parent if( $is_search && !empty($ancestors) ) { // reverse $ancestors = array_reverse($ancestors); // convert id's into titles foreach( $ancestors as $i => $id ) { $ancestors[ $i ] = get_the_title( $id ); } // append $append .= ' | ' . __('Parent', 'acf') . ': ' . implode(' / ', $ancestors); } } // merge $title = $prepend . $title . $append; // return return $title; } function acf_order_by_search( $array, $search ) { // vars $weights = array(); $needle = strtolower( $search ); // add key prefix foreach( array_keys($array) as $k ) { $array[ '_' . $k ] = acf_extract_var( $array, $k ); } // add search weight foreach( $array as $k => $v ) { // vars $weight = 0; $haystack = strtolower( $v ); $strpos = strpos( $haystack, $needle ); // detect search match if( $strpos !== false ) { // set eright to length of match $weight = strlen( $search ); // increase weight if match starts at begining of string if( $strpos == 0 ) { $weight++; } } // append to wights $weights[ $k ] = $weight; } // sort the array with menu_order ascending array_multisort( $weights, SORT_DESC, $array ); // remove key prefix foreach( array_keys($array) as $k ) { $array[ substr($k,1) ] = acf_extract_var( $array, $k ); } // return return $array; } /* * acf_get_pretty_user_roles * * description * * @type function * @date 23/02/2016 * @since 5.3.2 * * @param $post_id (int) * @return $post_id (int) */ function acf_get_pretty_user_roles( $allowed = false ) { // vars $editable_roles = get_editable_roles(); $allowed = acf_get_array($allowed); $roles = array(); // loop foreach( $editable_roles as $role_name => $role_details ) { // bail early if not allowed if( !empty($allowed) && !in_array($role_name, $allowed) ) continue; // append $roles[ $role_name ] = translate_user_role( $role_details['name'] ); } // return return $roles; } /* * acf_get_grouped_users * * This function will return all users grouped by role * This is handy for select settings * * @type function * @date 27/02/2014 * @since 5.0.0 * * @param $args (array) * @return (array) */ function acf_get_grouped_users( $args = array() ) { // vars $r = array(); // defaults $args = wp_parse_args( $args, array( 'users_per_page' => -1, 'paged' => 0, 'role' => '', 'orderby' => 'login', 'order' => 'ASC', )); // offset $i = 0; $min = 0; $max = 0; $users_per_page = acf_extract_var($args, 'users_per_page'); $paged = acf_extract_var($args, 'paged'); if( $users_per_page > 0 ) { // prevent paged from being -1 $paged = max(0, $paged); // set min / max $min = (($paged-1) * $users_per_page) + 1; // 1, 11 $max = ($paged * $users_per_page); // 10, 20 } // find array of post_type $user_roles = acf_get_pretty_user_roles($args['role']); // fix role if( is_array($args['role']) ) { // global global $wp_version, $wpdb; // vars $roles = acf_extract_var($args, 'role'); // new WP has role__in if( version_compare($wp_version, '4.4', '>=' ) ) { $args['role__in'] = $roles; // old WP doesn't have role__in } else { // vars $blog_id = get_current_blog_id(); $meta_query = array( 'relation' => 'OR' ); // loop foreach( $roles as $role ) { $meta_query[] = array( 'key' => $wpdb->get_blog_prefix( $blog_id ) . 'capabilities', 'value' => '"' . $role . '"', 'compare' => 'LIKE', ); } // append $args['meta_query'] = $meta_query; } } // get posts $users = get_users( $args ); // loop foreach( $user_roles as $user_role_name => $user_role_label ) { // vars $this_users = array(); $this_group = array(); // populate $this_posts foreach( array_keys($users) as $key ) { // bail ealry if not correct role if( !in_array($user_role_name, $users[ $key ]->roles) ) continue; // extract user $user = acf_extract_var( $users, $key ); // increase $i++; // bail ealry if too low if( $min && $i < $min ) continue; // bail early if too high (don't bother looking at any more users) if( $max && $i > $max ) break; // group by post type $this_users[ $user->ID ] = $user; } // bail early if no posts for this post type if( empty($this_users) ) continue; // append $r[ $user_role_label ] = $this_users; } // return return $r; } /* * acf_json_encode * * This function will return pretty JSON for all PHP versions * * @type function * @date 6/03/2014 * @since 5.0.0 * * @param $json (array) * @return (string) */ function acf_json_encode( $json ) { // PHP at least 5.4 if( version_compare(PHP_VERSION, '5.4.0', '>=') ) { return json_encode($json, JSON_PRETTY_PRINT); } // PHP less than 5.4 $json = json_encode($json); // http://snipplr.com/view.php?codeview&id=60559 $result = ''; $pos = 0; $strLen = strlen($json); $indentStr = " "; $newLine = "\n"; $prevChar = ''; $outOfQuotes = true; for ($i=0; $i<=$strLen; $i++) { // Grab the next character in the string. $char = substr($json, $i, 1); // Are we inside a quoted string? if ($char == '"' && $prevChar != '\\') { $outOfQuotes = !$outOfQuotes; // If this character is the end of an element, // output a new line and indent the next line. } else if(($char == '}' || $char == ']') && $outOfQuotes) { $result .= $newLine; $pos --; for ($j=0; $j<$pos; $j++) { $result .= $indentStr; } } // Add the character to the result string. $result .= $char; // If this character is ':' adda space after it if($char == ':' && $outOfQuotes) { $result .= ' '; } // If the last character was the beginning of an element, // output a new line and indent the next line. if (($char == ',' || $char == '{' || $char == '[') && $outOfQuotes) { $result .= $newLine; if ($char == '{' || $char == '[') { $pos ++; } for ($j = 0; $j < $pos; $j++) { $result .= $indentStr; } } $prevChar = $char; } // return return $result; } /* * acf_str_exists * * This function will return true if a sub string is found * * @type function * @date 1/05/2014 * @since 5.0.0 * * @param $needle (string) * @param $haystack (string) * @return (boolean) */ function acf_str_exists( $needle, $haystack ) { // return true if $haystack contains the $needle if( is_string($haystack) && strpos($haystack, $needle) !== false ) { return true; } // return return false; } /* * acf_debug * * description * * @type function * @date 2/05/2014 * @since 5.0.0 * * @param $post_id (int) * @return $post_id (int) */ function acf_debug() { // vars $args = func_get_args(); $s = array_shift($args); $o = ''; $nl = "\r\n"; // start script $o .= '' . $nl; // echo echo $o; } function acf_debug_start() { acf_update_setting( 'debug_start', memory_get_usage()); } function acf_debug_end() { $start = acf_get_setting( 'debug_start' ); $end = memory_get_usage(); return $end - $start; } /* * acf_get_updates * * This function will reutrn all or relevant updates for ACF * * @type function * @date 12/05/2014 * @since 5.0.0 * * @param $post_id (int) * @return $post_id (int) */ function acf_get_updates() { // vars $updates = array(); $plugin_version = acf_get_setting('version'); $acf_version = get_option('acf_version'); $path = acf_get_path('admin/updates'); // bail early if no version (not activated) if( !$acf_version ) { return false; } // check that path exists if( !file_exists( $path ) ) { return false; } $dir = opendir( $path ); while(false !== ( $file = readdir($dir)) ) { // only php files if( substr($file, -4) !== '.php' ) { continue; } // get version number $update_version = substr($file, 0, -4); // ignore if update is for a future version. May exist for testing if( version_compare( $update_version, $plugin_version, '>') ) { continue; } // ignore if update has already been run if( version_compare( $update_version, $acf_version, '<=') ) { continue; } // append $updates[] = $update_version; } // return return $updates; } /* * acf_encode_choices * * description * * @type function * @date 4/06/2014 * @since 5.0.0 * * @param $post_id (int) * @return $post_id (int) */ function acf_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( $k === $v ) continue; // show key in the value $array[ $k ] = $k . ' : ' . $v; } } // implode $string = implode("\n", $array); // return return $string; } function acf_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( acf_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; } /* * acf_str_replace * * This function will replace an array of strings much like str_replace * The difference is the extra logic to avoid replacing a string that has alread been replaced * This is very useful for replacing date characters as they overlap with eachother * * @type function * @date 21/06/2016 * @since 5.3.8 * * @param $post_id (int) * @return $post_id (int) */ function acf_str_replace( $string, $search_replace ) { // vars $ignore = array(); // remove potential empty search to avoid PHP error unset($search_replace['']); // loop over conversions foreach( $search_replace as $search => $replace ) { // ignore this search, it was a previous replace if( in_array($search, $ignore) ) continue; // bail early if subsctring not found if( strpos($string, $search) === false ) continue; // replace $string = str_replace($search, $replace, $string); // append to ignore $ignore[] = $replace; } // return return $string; } /* * date & time formats * * These settings contain an association of format strings from PHP => JS * * @type function * @date 21/06/2016 * @since 5.3.8 * * @param n/a * @return n/a */ acf_update_setting('php_to_js_date_formats', array( // Year 'Y' => 'yy', // Numeric, 4 digits 1999, 2003 'y' => 'y', // Numeric, 2 digits 99, 03 // Month 'm' => 'mm', // Numeric, with leading zeros 01–12 'n' => 'm', // Numeric, without leading zeros 1–12 'F' => 'MM', // Textual full January – December 'M' => 'M', // Textual three letters Jan - Dec // Weekday 'l' => 'DD', // Full name (lowercase 'L') Sunday – Saturday 'D' => 'D', // Three letter name Mon – Sun // Day of Month 'd' => 'dd', // Numeric, with leading zeros 01–31 'j' => 'd', // Numeric, without leading zeros 1–31 'S' => '', // The English suffix for the day of the month st, nd or th in the 1st, 2nd or 15th. )); acf_update_setting('php_to_js_time_formats', array( 'a' => 'tt', // Lowercase Ante meridiem and Post meridiem am or pm 'A' => 'TT', // Uppercase Ante meridiem and Post meridiem AM or PM 'h' => 'hh', // 12-hour format of an hour with leading zeros 01 through 12 'g' => 'h', // 12-hour format of an hour without leading zeros 1 through 12 'H' => 'HH', // 24-hour format of an hour with leading zeros 00 through 23 'G' => 'H', // 24-hour format of an hour without leading zeros 0 through 23 'i' => 'mm', // Minutes with leading zeros 00 to 59 's' => 'ss', // Seconds, with leading zeros 00 through 59 )); /* * acf_split_date_time * * This function will split a format string into seperate date and time * * @type function * @date 26/05/2016 * @since 5.3.8 * * @param $date_time (string) * @return $formats (array) */ function acf_split_date_time( $date_time = '' ) { // vars $php_date = acf_get_setting('php_to_js_date_formats'); $php_time = acf_get_setting('php_to_js_time_formats'); $chars = str_split($date_time); $type = 'date'; // default $data = array( 'date' => '', 'time' => '' ); // loop foreach( $chars as $i => $c ) { // find type // - allow misc characters to append to previous type if( isset($php_date[ $c ]) ) { $type = 'date'; } elseif( isset($php_time[ $c ]) ) { $type = 'time'; } // append char $data[ $type ] .= $c; } // trim $data['date'] = trim($data['date']); $data['time'] = trim($data['time']); // return return $data; } /* * acf_convert_date_to_php * * This fucntion converts a date format string from JS to PHP * * @type function * @date 20/06/2014 * @since 5.0.0 * * @param $date (string) * @return (string) */ function acf_convert_date_to_php( $date = '' ) { // vars $php_to_js = acf_get_setting('php_to_js_date_formats'); $js_to_php = array_flip($php_to_js); // return return acf_str_replace( $date, $js_to_php ); } /* * acf_convert_date_to_js * * This fucntion converts a date format string from PHP to JS * * @type function * @date 20/06/2014 * @since 5.0.0 * * @param $date (string) * @return (string) */ function acf_convert_date_to_js( $date = '' ) { // vars $php_to_js = acf_get_setting('php_to_js_date_formats'); // return return acf_str_replace( $date, $php_to_js ); } /* * acf_convert_time_to_php * * This fucntion converts a time format string from JS to PHP * * @type function * @date 20/06/2014 * @since 5.0.0 * * @param $time (string) * @return (string) */ function acf_convert_time_to_php( $time = '' ) { // vars $php_to_js = acf_get_setting('php_to_js_time_formats'); $js_to_php = array_flip($php_to_js); // return return acf_str_replace( $time, $js_to_php ); } /* * acf_convert_time_to_js * * This fucntion converts a date format string from PHP to JS * * @type function * @date 20/06/2014 * @since 5.0.0 * * @param $time (string) * @return (string) */ function acf_convert_time_to_js( $time = '' ) { // vars $php_to_js = acf_get_setting('php_to_js_time_formats'); // return return acf_str_replace( $time, $php_to_js ); } /* * acf_update_user_setting * * description * * @type function * @date 15/07/2014 * @since 5.0.0 * * @param $post_id (int) * @return $post_id (int) */ function acf_update_user_setting( $name, $value ) { // get current user id $user_id = get_current_user_id(); // get user settings $settings = get_user_meta( $user_id, 'acf_user_settings', true ); // ensure array $settings = acf_get_array($settings); // delete setting (allow 0 to save) if( acf_is_empty($value) ) { unset($settings[ $name ]); // append setting } else { $settings[ $name ] = $value; } // update user data return update_metadata('user', $user_id, 'acf_user_settings', $settings); } /* * acf_get_user_setting * * description * * @type function * @date 15/07/2014 * @since 5.0.0 * * @param $post_id (int) * @return $post_id (int) */ function acf_get_user_setting( $name = '', $default = false ) { // get current user id $user_id = get_current_user_id(); // get user settings $settings = get_user_meta( $user_id, 'acf_user_settings', true ); // ensure array $settings = acf_get_array($settings); // bail arly if no settings if( !isset($settings[$name]) ) return $default; // return return $settings[$name]; } /* * acf_in_array * * description * * @type function * @date 22/07/2014 * @since 5.0.0 * * @param $post_id (int) * @return $post_id (int) */ function acf_in_array( $value = '', $array = false ) { // bail early if not array if( !is_array($array) ) return false; // find value in array return in_array($value, $array); } /* * acf_get_valid_post_id * * This function will return a valid post_id based on the current screen / parameter * * @type function * @date 8/12/2013 * @since 5.0.0 * * @param $post_id (mixed) * @return $post_id (mixed) */ function acf_get_valid_post_id( $post_id = 0 ) { // if not $post_id, load queried object if( !$post_id ) { // try for global post (needed for setup_postdata) $post_id = (int) get_the_ID(); // try for current screen if( !$post_id ) { $post_id = get_queried_object(); } } // $post_id may be an object if( is_object($post_id) ) { // post if( isset($post_id->post_type, $post_id->ID) ) { $post_id = $post_id->ID; // user } elseif( isset($post_id->roles, $post_id->ID) ) { $post_id = 'user_' . $post_id->ID; // term } elseif( isset($post_id->taxonomy, $post_id->term_id) ) { $post_id = $post_id->taxonomy . '_' . $post_id->term_id; // comment } elseif( isset($post_id->comment_ID) ) { $post_id = 'comment_' . $post_id->comment_ID; // default } else { $post_id = 0; } } // allow for option == options if( $post_id === 'option' ) { $post_id = 'options'; } // append language code if( $post_id == 'options' ) { $dl = acf_get_setting('default_language'); $cl = acf_get_setting('current_language'); if( $cl && $cl !== $dl ) { $post_id .= '_' . $cl; } } /* * Override for preview * * If the $_GET['preview_id'] is set, then the user wants to see the preview data. * There is also the case of previewing a page with post_id = 1, but using get_field * to load data from another post_id. * In this case, we need to make sure that the autosave revision is actually related * to the $post_id variable. If they match, then the autosave data will be used, otherwise, * the user wants to load data from a completely different post_id */ if( isset($_GET['preview_id']) ) { $autosave = wp_get_post_autosave( $_GET['preview_id'] ); if( $autosave && $autosave->post_parent == $post_id ) { $post_id = (int) $autosave->ID; } } elseif( isset($_GET['p']) && isset($_GET['preview']) ) { $revision = acf_get_post_latest_revision( $_GET['p'] ); // save if( $revision && $revision->post_parent == $post_id) { $post_id = (int) $revision->ID; } } // return return $post_id; } /* * acf_get_post_id_info * * This function will return the type and id for a given $post_id string * * @type function * @date 2/07/2016 * @since 5.4.0 * * @param $post_id (mixed) * @return $info (array) */ function acf_get_post_id_info( $post_id = 0 ) { // vars $info = array( 'type' => 'post', 'id' => 0 ); // bail early if no $post_id if( !$post_id ) return $info; // check cache // - this function will most likely be called multiple times (saving loading fields from post) //$cache_key = "get_post_id_info/post_id={$post_id}"; //if( acf_isset_cache($cache_key) ) return acf_get_cache($cache_key); // numeric if( is_numeric($post_id) ) { $info['id'] = (int) $post_id; // string } elseif( is_string($post_id) ) { // vars $glue = '_'; $type = explode($glue, $post_id); $id = array_pop($type); $type = implode($glue, $type); $meta = array('post', 'user', 'comment'); // add in 'term' // meta if( is_numeric($id) && in_array($type, $meta) ) { $info['type'] = $type; $info['id'] = (int) $id; // option } else { $info['type'] = 'option'; $info['id'] = $post_id; } } // update cache //acf_set_cache($cache_key, $info); // return return $info; } /* echo '
'; print_r( acf_get_post_id_info(4) ); echo ''; echo '
';
print_r( acf_get_post_id_info('post_4') );
echo '';
echo '';
print_r( acf_get_post_id_info('user_123') );
echo '';
echo '';
print_r( acf_get_post_id_info('term_567') );
echo '';
echo '';
print_r( acf_get_post_id_info('comment_6') );
echo '';
echo '';
print_r( acf_get_post_id_info('options_lol!') );
echo '';
echo '';
print_r( acf_get_post_id_info('option') );
echo '';
echo '';
print_r( acf_get_post_id_info('options') );
echo '';
die;
*/
/*
* acf_upload_files
*
* This function will walk througfh the $_FILES data and upload each found
*
* @type function
* @date 25/10/2014
* @since 5.0.9
*
* @param $ancestors (array) an internal parameter, not required
* @return n/a
*/
function acf_upload_files( $ancestors = array() ) {
// vars
$file = array(
'name' => '',
'type' => '',
'tmp_name' => '',
'error' => '',
'size' => ''
);
// populate with $_FILES data
foreach( array_keys($file) as $k ) {
$file[ $k ] = $_FILES['acf'][ $k ];
}
// walk through ancestors
if( !empty($ancestors) ) {
foreach( $ancestors as $a ) {
foreach( array_keys($file) as $k ) {
$file[ $k ] = $file[ $k ][ $a ];
}
}
}
// is array?
if( is_array($file['name']) ) {
foreach( array_keys($file['name']) as $k ) {
$_ancestors = array_merge($ancestors, array($k));
acf_upload_files( $_ancestors );
}
return;
}
// bail ealry if file has error (no file uploaded)
if( $file['error'] ) {
return;
}
// assign global _acfuploader for media validation
$_POST['_acfuploader'] = end($ancestors);
// file found!
$attachment_id = acf_upload_file( $file );
// update $_POST
array_unshift($ancestors, 'acf');
acf_update_nested_array( $_POST, $ancestors, $attachment_id );
}
/*
* acf_upload_file
*
* This function will uploade a $_FILE
*
* @type function
* @date 27/10/2014
* @since 5.0.9
*
* @param $uploaded_file (array) array found from $_FILE data
* @return $id (int) new attachment ID
*/
function acf_upload_file( $uploaded_file ) {
// required
//require_once( ABSPATH . "/wp-load.php" ); // WP should already be loaded
require_once( ABSPATH . "/wp-admin/includes/media.php" ); // video functions
require_once( ABSPATH . "/wp-admin/includes/file.php" );
require_once( ABSPATH . "/wp-admin/includes/image.php" );
// required for wp_handle_upload() to upload the file
$upload_overrides = array( 'test_form' => false );
// upload
$file = wp_handle_upload( $uploaded_file, $upload_overrides );
// bail ealry if upload failed
if( isset($file['error']) ) {
return $file['error'];
}
// vars
$url = $file['url'];
$type = $file['type'];
$file = $file['file'];
$filename = basename($file);
// Construct the object array
$object = array(
'post_title' => $filename,
'post_mime_type' => $type,
'guid' => $url,
'context' => 'acf-upload'
);
// Save the data
$id = wp_insert_attachment($object, $file);
// Add the meta-data
wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $file ) );
/** This action is documented in wp-admin/custom-header.php */
do_action( 'wp_create_file_in_uploads', $file, $id ); // For replication
// return new ID
return $id;
}
/*
* acf_update_nested_array
*
* This function will update a nested array value. Useful for modifying the $_POST array
*
* @type function
* @date 27/10/2014
* @since 5.0.9
*
* @param $array (array) target array to be updated
* @param $ancestors (array) array of keys to navigate through to find the child
* @param $value (mixed) The new value
* @return (boolean)
*/
function acf_update_nested_array( &$array, $ancestors, $value ) {
// if no more ancestors, update the current var
if( empty($ancestors) ) {
$array = $value;
// return
return true;
}
// shift the next ancestor from the array
$k = array_shift( $ancestors );
// if exists
if( isset($array[ $k ]) ) {
return acf_update_nested_array( $array[ $k ], $ancestors, $value );
}
// return
return false;
}
/*
* acf_is_screen
*
* This function will return true if all args are matched for the current screen
*
* @type function
* @date 9/12/2014
* @since 5.1.5
*
* @param $post_id (int)
* @return $post_id (int)
*/
function acf_is_screen( $id = '' ) {
// bail early if not defined
if( !function_exists('get_current_screen') ) return false;
// vars
$current_screen = get_current_screen();
// bail early if no screen
if( !$current_screen ) return false;
// return
return ($id === $current_screen->id);
}
/*
* acf_maybe_get
*
* This function will return a var if it exists in an array
*
* @type function
* @date 9/12/2014
* @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 $post_id (int)
*/
function acf_maybe_get( $array, $key, $default = null ) {
// vars
$keys = explode('/', $key);
// loop through keys
foreach( $keys as $k ) {
// return default if does not exist
if( !isset($array[ $k ]) ) {
return $default;
}
// update $array
$array = $array[ $k ];
}
// return
return $array;
}
/*
* acf_get_attachment
*
* This function will return an array of attachment data
*
* @type function
* @date 5/01/2015
* @since 5.1.5
*
* @param $post (mixed) either post ID or post object
* @return (array)
*/
function acf_get_attachment( $post ) {
// post
$post = get_post($post);
// bail early if no post
if( !$post ) return false;
// vars
$thumb_id = 0;
$id = $post->ID;
$a = array(
'ID' => $id,
'id' => $id,
'title' => $post->post_title,
'filename' => wp_basename( $post->guid ),
'url' => wp_get_attachment_url( $id ),
'alt' => get_post_meta($id, '_wp_attachment_image_alt', true),
'author' => $post->post_author,
'description' => $post->post_content,
'caption' => $post->post_excerpt,
'name' => $post->post_name,
'date' => $post->post_date_gmt,
'modified' => $post->post_modified_gmt,
'mime_type' => $post->post_mime_type,
'type' => acf_maybe_get( explode('/', $post->post_mime_type), 0, '' ),
'icon' => wp_mime_type_icon( $id )
);
// video may use featured image
if( $a['type'] === 'image' ) {
$thumb_id = $id;
$src = wp_get_attachment_image_src( $id, 'full' );
$a['url'] = $src[0];
$a['width'] = $src[1];
$a['height'] = $src[2];
} elseif( $a['type'] === 'audio' || $a['type'] === 'video' ) {
// video dimentions
if( $a['type'] == 'video' ) {
$meta = wp_get_attachment_metadata( $id );
$a['width'] = acf_maybe_get($meta, 'width', 0);
$a['height'] = acf_maybe_get($meta, 'height', 0);
}
// feature image
if( $featured_id = get_post_thumbnail_id($id) ) {
$thumb_id = $featured_id;
}
}
// sizes
if( $thumb_id ) {
// find all image sizes
if( $sizes = get_intermediate_image_sizes() ) {
$a['sizes'] = array();
foreach( $sizes as $size ) {
// url
$src = wp_get_attachment_image_src( $thumb_id, $size );
// add src
$a['sizes'][ $size ] = $src[0];
$a['sizes'][ $size . '-width' ] = $src[1];
$a['sizes'][ $size . '-height' ] = $src[2];
}
}
}
// return
return $a;
}
/*
* acf_get_truncated
*
* This function will truncate and return a string
*
* @type function
* @date 8/08/2014
* @since 5.0.0
*
* @param $text (string)
* @param $length (int)
* @return (string)
*/
function acf_get_truncated( $text, $length = 64 ) {
// vars
$text = trim($text);
$the_length = strlen( $text );
// cut
$return = substr( $text, 0, ($length - 3) );
// ...
if( $the_length > ($length - 3) ) {
$return .= '...';
}
// return
return $return;
}
/*
* acf_get_current_url
*
* This function will return the current URL
*
* @type function
* @date 23/01/2015
* @since 5.1.5
*
* @param n/a
* @return (string)
*/
function acf_get_current_url() {
// vars
$home = home_url();
$url = home_url($_SERVER['REQUEST_URI']);
// test
//$home = 'http://acf5/dev/wp-admin';
//$url = $home . '/dev/wp-admin/api-template/acf_form';
// explode url (4th bit is the sub folder)
$bits = explode('/', $home, 4);
/*
Array (
[0] => http:
[1] =>
[2] => acf5
[3] => dev
)
*/
// handle sub folder
if( !empty($bits[3]) ) {
$find = '/' . $bits[3];
$pos = strpos($url, $find);
$length = strlen($find);
if( $pos !== false ) {
$url = substr_replace($url, '', $pos, $length);
}
}
// return
return $url;
}
/*
* acf_current_user_can_admin
*
* This function will return true if the current user can administrate the ACF field groups
*
* @type function
* @date 9/02/2015
* @since 5.1.5
*
* @param $post_id (int)
* @return $post_id (int)
*/
function acf_current_user_can_admin() {
if( acf_get_setting('show_admin') && current_user_can(acf_get_setting('capability')) ) {
return true;
}
// return
return false;
}
/*
* acf_get_filesize
*
* This function will return a numeric value of bytes for a given filesize string
*
* @type function
* @date 18/02/2015
* @since 5.1.5
*
* @param $size (mixed)
* @return (int)
*/
function acf_get_filesize( $size = 1 ) {
// vars
$unit = 'MB';
$units = array(
'TB' => 4,
'GB' => 3,
'MB' => 2,
'KB' => 1,
);
// look for $unit within the $size parameter (123 KB)
if( is_string($size) ) {
// vars
$custom = strtoupper( substr($size, -2) );
foreach( $units as $k => $v ) {
if( $custom === $k ) {
$unit = $k;
$size = substr($size, 0, -2);
}
}
}
// calc bytes
$bytes = floatval($size) * pow(1024, $units[$unit]);
// return
return $bytes;
}
/*
* acf_format_filesize
*
* This function will return a formatted string containing the filesize and unit
*
* @type function
* @date 18/02/2015
* @since 5.1.5
*
* @param $size (mixed)
* @return (int)
*/
function acf_format_filesize( $size = 1 ) {
// convert
$bytes = acf_get_filesize( $size );
// vars
$units = array(
'TB' => 4,
'GB' => 3,
'MB' => 2,
'KB' => 1,
);
// loop through units
foreach( $units as $k => $v ) {
$result = $bytes / pow(1024, $v);
if( $result >= 1 ) {
return $result . ' ' . $k;
}
}
// return
return $bytes . ' B';
}
/*
* acf_get_valid_terms
*
* This function will replace old terms with new split term ids
*
* @type function
* @date 27/02/2015
* @since 5.1.5
*
* @param $terms (int|array)
* @param $taxonomy (string)
* @return $terms
*/
function acf_get_valid_terms( $terms = false, $taxonomy = 'category' ) {
// force into array
$terms = acf_get_array($terms);
// force ints
$terms = array_map('intval', $terms);
// bail early if function does not yet exist or
if( !function_exists('wp_get_split_term') || empty($terms) ) {
return $terms;
}
// attempt to find new terms
foreach( $terms as $i => $term_id ) {
$new_term_id = wp_get_split_term($term_id, $taxonomy);
if( $new_term_id ) {
$terms[ $i ] = $new_term_id;
}
}
// return
return $terms;
}
/*
* acf_esc_html_deep
*
* Navigates through an array and escapes html from the values.
*
* @type function
* @date 10/06/2015
* @since 5.2.7
*
* @param $value (mixed)
* @return $value
*/
/*
function acf_esc_html_deep( $value ) {
// array
if( is_array($value) ) {
$value = array_map('acf_esc_html_deep', $value);
// object
} elseif( is_object($value) ) {
$vars = get_object_vars( $value );
foreach( $vars as $k => $v ) {
$value->{$k} = acf_esc_html_deep( $v );
}
// string
} elseif( is_string($value) ) {
$value = esc_html($value);
}
// return
return $value;
}
*/
/*
* acf_validate_attachment
*
* This function will validate an attachment based on a field's resrictions and return an array of errors
*
* @type function
* @date 3/07/2015
* @since 5.2.3
*
* @param $attachment (array) attachment data. Cahnges based on context
* @param $field (array) field settings containing restrictions
* @param $context (string) $file is different when uploading / preparing
* @return $errors (array)
*/
function acf_validate_attachment( $attachment, $field, $context = 'prepare' ) {
// vars
$errors = array();
$file = array(
'type' => '',
'width' => 0,
'height' => 0,
'size' => 0
);
// upload
if( $context == 'upload' ) {
// vars
$file['type'] = pathinfo($attachment['name'], PATHINFO_EXTENSION);
$file['size'] = filesize($attachment['tmp_name']);
if( strpos($attachment['type'], 'image') !== false ) {
$size = getimagesize($attachment['tmp_name']);
$file['width'] = acf_maybe_get($size, 0);
$file['height'] = acf_maybe_get($size, 1);
}
// prepare
} elseif( $context == 'prepare' ) {
$file['type'] = pathinfo($attachment['url'], PATHINFO_EXTENSION);
$file['size'] = acf_maybe_get($attachment, 'filesizeInBytes', 0);
$file['width'] = acf_maybe_get($attachment, 'width', 0);
$file['height'] = acf_maybe_get($attachment, 'height', 0);
// custom
} else {
$file = wp_parse_args($file, $attachment);
}
// image
if( $file['width'] || $file['height'] ) {
// width
$min_width = (int) acf_maybe_get($field, 'min_width', 0);
$max_width = (int) acf_maybe_get($field, 'max_width', 0);
if( $file['width'] ) {
if( $min_width && $file['width'] < $min_width ) {
// min width
$errors['min_width'] = sprintf(__('Image width must be at least %dpx.', 'acf'), $min_width );
} elseif( $max_width && $file['width'] > $max_width ) {
// min width
$errors['max_width'] = sprintf(__('Image width must not exceed %dpx.', 'acf'), $max_width );
}
}
// height
$min_height = (int) acf_maybe_get($field, 'min_height', 0);
$max_height = (int) acf_maybe_get($field, 'max_height', 0);
if( $file['height'] ) {
if( $min_height && $file['height'] < $min_height ) {
// min height
$errors['min_height'] = sprintf(__('Image height must be at least %dpx.', 'acf'), $min_height );
} elseif( $max_height && $file['height'] > $max_height ) {
// min height
$errors['max_height'] = sprintf(__('Image height must not exceed %dpx.', 'acf'), $max_height );
}
}
}
// file size
if( $file['size'] ) {
$min_size = acf_maybe_get($field, 'min_size', 0);
$max_size = acf_maybe_get($field, 'max_size', 0);
if( $min_size && $file['size'] < acf_get_filesize($min_size) ) {
// min width
$errors['min_size'] = sprintf(__('File size must be at least %s.', 'acf'), acf_format_filesize($min_size) );
} elseif( $max_size && $file['size'] > acf_get_filesize($max_size) ) {
// min width
$errors['max_size'] = sprintf(__('File size must must not exceed %s.', 'acf'), acf_format_filesize($max_size) );
}
}
// file type
if( $file['type'] ) {
$mime_types = acf_maybe_get($field, 'mime_types', '');
// lower case
$file['type'] = strtolower($file['type']);
$mime_types = strtolower($mime_types);
// explode
$mime_types = str_replace(array(' ', '.'), '', $mime_types);
$mime_types = explode(',', $mime_types); // split pieces
$mime_types = array_filter($mime_types); // remove empty pieces
if( !empty($mime_types) && !in_array($file['type'], $mime_types) ) {
// glue together last 2 types
if( count($mime_types) > 1 ) {
$last1 = array_pop($mime_types);
$last2 = array_pop($mime_types);
$mime_types[] = $last2 . ' ' . __('or', 'acf') . ' ' . $last1;
}
$errors['mime_types'] = sprintf(__('File type must be %s.', 'acf'), implode(', ', $mime_types) );
}
}
// filter for 3rd party customization
$errors = apply_filters("acf/validate_attachment", $errors, $file, $attachment, $field);
$errors = apply_filters("acf/validate_attachment/type={$field['type']}", $errors, $file, $attachment, $field );
$errors = apply_filters("acf/validate_attachment/name={$field['name']}", $errors, $file, $attachment, $field );
$errors = apply_filters("acf/validate_attachment/key={$field['key']}", $errors, $file, $attachment, $field );
// return
return $errors;
}
/*
* _acf_settings_uploader
*
* Dynamic logic for uploader setting
*
* @type function
* @date 7/05/2015
* @since 5.2.3
*
* @param $uploader (string)
* @return $uploader
*/
add_filter('acf/settings/uploader', '_acf_settings_uploader');
function _acf_settings_uploader( $uploader ) {
// if can't upload files
if( !current_user_can('upload_files') ) {
$uploader = 'basic';
}
// return
return $uploader;
}
/*
* acf_translate_keys
*
* description
*
* @type function
* @date 7/12/2015
* @since 5.3.2
*
* @param $post_id (int)
* @return $post_id (int)
*/
/*
function acf_translate_keys( $array, $keys ) {
// bail early if no keys
if( empty($keys) ) return $array;
// translate
foreach( $keys as $k ) {
// bail ealry if not exists
if( !isset($array[ $k ]) ) continue;
// translate
$array[ $k ] = acf_translate( $array[ $k ] );
}
// return
return $array;
}
*/
/*
* acf_translate
*
* This function will translate a string using the new 'l10n_textdomain' setting
* Also works for arrays which is great for fields - select -> choices
*
* @type function
* @date 4/12/2015
* @since 5.3.2
*
* @param $string (mixed) string or array containins strings to be translated
* @return $string
*/
function acf_translate( $string ) {
// bail early if not enabled
if( !acf_get_setting('l10n') ) return $string;
// bail early if no textdomain
if( !acf_get_setting('l10n_textdomain') ) return $string;
// is array
if( is_array($string) ) {
return array_map('acf_translate', $string);
}
// bail early if not string
if( !is_string($string) ) return $string;
// bail early if empty
if( $string === '' ) return $string;
// allow for var_export export
if( acf_get_setting('l10n_var_export') ){
return "!!__(!!'" . $string . "!!', !!'" . acf_get_setting('l10n_textdomain') . "!!')!!";
}
// vars
return __( $string, acf_get_setting('l10n_textdomain') );
}
/*
* acf_maybe_add_action
*
* This function will determine if the action has already run before adding / calling the function
*
* @type function
* @date 13/01/2016
* @since 5.3.2
*
* @param $post_id (int)
* @return $post_id (int)
*/
function acf_maybe_add_action( $tag, $function_to_add, $priority = 10, $accepted_args = 1 ) {
// if action has already run, execute it
if( did_action($tag) ) {
call_user_func( $function_to_add );
// if action has not yet run, add it
} else {
add_action( $tag, $function_to_add, $priority, $accepted_args );
}
}
/*
* acf_is_row_collapsed
*
* This function will return true if the field's row is collapsed
*
* @type function
* @date 2/03/2016
* @since 5.3.2
*
* @param $post_id (int)
* @return $post_id (int)
*/
function acf_is_row_collapsed( $field_key = '', $row_index = 0 ) {
// collapsed
$collapsed = acf_get_user_setting('collapsed_' . $field_key, '');
// cookie fallback ( version < 5.3.2 )
if( $collapsed === '' ) {
$collapsed = acf_extract_var($_COOKIE, "acf_collapsed_{$field_key}", '');
$collapsed = str_replace('|', ',', $collapsed);
// update
acf_update_user_setting( 'collapsed_' . $field_key, $collapsed );
}
// explode
$collapsed = explode(',', $collapsed);
$collapsed = array_filter($collapsed, 'is_numeric');
// collapsed class
return in_array($row_index, $collapsed);
}
/*
* acf_get_post_thumbnail
*
* This function will return a thumbail image url for a given post
*
* @type function
* @date 3/05/2016
* @since 5.3.8
*
* @param $post (obj)
* @param $size (mixed)
* @return (string)
*/
function acf_get_post_thumbnail( $post = null, $size = 'thumbnail' ) {
// vars
$data = array(
'url' => '',
'type' => '',
'html' => ''
);
// post
$post = get_post($post);
// bail early if no post
if( !$post ) return $data;
// vars
$thumb_id = $post->ID;
$mime_type = acf_maybe_get(explode('/', $post->post_mime_type), 0);
// attachment
if( $post->post_type === 'attachment' ) {
// change $thumb_id
if( $mime_type === 'audio' || $mime_type === 'video' ) {
$thumb_id = get_post_thumbnail_id($post->ID);
}
// post
} else {
$thumb_id = get_post_thumbnail_id($post->ID);
}
// try url
$data['url'] = wp_get_attachment_image_src($thumb_id, $size);
$data['url'] = acf_maybe_get($data['url'], 0);
// default icon
if( !$data['url'] && $post->post_type === 'attachment' ) {
$data['url'] = wp_mime_type_icon($post->ID);
$data['type'] = 'icon';
}
// html
$data['html'] = '