I might have fixed it myself, hopefully someone can tell me if this is wise or not, but I added to the query from the tutorial:
GROUP BY meta_key
the the full query is now:
$rows = $wpdb->get_results($wpdb->prepare(
"
SELECT *
FROM {$wpdb->prefix}postmeta
WHERE meta_key LIKE %s
AND meta_value = %s
GROUP BY meta_key",
'friend_partner_entry_%_show_logo_on_home', // meta_name: $ParentName_$RowNumber_$ChildName
'1' // meta_value: 'type_3' for example
));
I forgot to post my query:
$rows = $wpdb->get_results($wpdb->prepare(
"
SELECT *
FROM {$wpdb->prefix}postmeta
WHERE meta_key LIKE %s
AND meta_value = %s
",
'friend_partner_entry_%_show_logo_on_home', // meta_name: $ParentName_$RowNumber_$ChildName
'1' // meta_value: 'type_3' for example
));
There are 2 ways that I can think of to do this.
First the hard way
The first thing you’re going to need to do is to create custom rewrite rules https://codex.wordpress.org/Rewrite_API/add_rewrite_rule
The next thing you’ll need to do is create a pre_get_posts filter to alter the query based on those rewrite rules https://codex.wordpress.org/Plugin_API/Action_Reference/pre_get_posts
And finally you will need to create a filter to alter all of the permalinks for the taxonomy or post type, whatever it is that %sku%
in /%custom-post-type%/%custom-taxonomy%/%sku%/
represents.
Then the easy way
Create an acf/save_post filter https://www.advancedcustomfields.com/resources/acfsave_post/ and in this filter get the value of the sku field and update the post slug to match this value. The problem with this is the you need to make sure that the value entered for sku is unique. I have outlined how to do this here https://support.advancedcustomfields.com/forums/topic/accept-only-unique-values/
You need to use the $rows
variable that holds the wpdb result. Something like this:
$rows = $wpdb->get_results($wpdb->prepare(
"
SELECT *
FROM {$wpdb->prefix}postmeta
WHERE meta_key LIKE %s
",
'calendrier_%_jour_debut'
));
// vars
$order = array();
// populate order
foreach( $rows as $i => $row ) {
$order[ $i ] = $row['meta_value'];
}
// multisort
array_multisort( $order, SORT_ASC, $rows );
// Temporary month variable
$current_month = null;
// Loop through the returned rows
foreach( $rows as $row){
// Convert the date string to PHP datetime
$date = DateTime::createFromFormat('Ymd', $row['meta_value']);
// Get the month
$month = $date->format('F');
// Echo the months only once
if( $current_month != $month ){
echo $month . "\r\n";
$current_month = $month;
}
// Show the date string
echo $row['meta_value'] . "\r\n";
// Get the related post
$thepost = get_post($row['post_id']);
// Show it if you want
print_r($thepost);
// Get the event repeater for the related post
$calendrier = get_field('calendrier', $thepost->ID);
// Show it if you want
print_r($calendrier);
}
Hope this helps 🙂
hi james,
Thank you for your help.
here is my current code
<?php
/**
* Template Name: Calendrier
*/
?>
<?php get_header(); ?>
<?php
$rows = $wpdb->get_results($wpdb->prepare(
"
SELECT *
FROM {$wpdb->prefix}postmeta
WHERE meta_key LIKE %s
",
'calendrier_%_jour_debut'
));
/// var_dump($rows);
/*
array(5) {
[0]=>
object(stdClass)#6662 (4) {
["meta_id"]=>
string(4) "1956"
["post_id"]=>
string(3) "408"
["meta_key"]=>
string(23) "calendrier_0_jour_debut"
["meta_value"]=>
string(8) "20160704"
}
[1]=>
object(stdClass)#6676 (4) {
["meta_id"]=>
string(4) "2183"
["post_id"]=>
string(3) "441"
["meta_key"]=>
string(23) "calendrier_0_jour_debut"
["meta_value"]=>
string(8) "20160910"
}
[2]=>
object(stdClass)#6717 (4) {
["meta_id"]=>
string(4) "2204"
["post_id"]=>
string(3) "442"
["meta_key"]=>
string(23) "calendrier_0_jour_debut"
["meta_value"]=>
string(8) "20160927"
}
[3]=>
object(stdClass)#6716 (4) {
["meta_id"]=>
string(4) "1972"
["post_id"]=>
string(3) "408"
["meta_key"]=>
string(23) "calendrier_1_jour_debut"
["meta_value"]=>
string(8) "20160924"
}
[4]=>
object(stdClass)#6715 (4) {
["meta_id"]=>
string(4) "1990"
["post_id"]=>
string(3) "408"
["meta_key"]=>
string(23) "calendrier_2_jour_debut"
["meta_value"]=>
string(8) "20160709"
}
} */
$rows = get_field ('calendrier');
// var_dump($rows); = NULL
// vars
$order = array();
// populate order
foreach( $repeater as $i => $row ) {
$order[ $i ] = $row['id'];
}
//var_dump($order);
/*
array(0) {
}
*/
?>
<?php get_footer(); ?>
:s
Here is an example of useage in a loop. It’s not particularly long so I’m just pasting it here. Relevant code is on line 64, JSON is attached.
<?php
/*
Template Name: Current Semester
*/
get_header('courses');
$semester = get_field('current_semester', 'option');
?>
<div class="content width" role="main">
<div class="page">
<?php get_sidebar('courses'); ?>
<section class="content-container">
<div id="regular-content">
<!-- Undergraduate -->
<?php
$ud_args = array(
'post_type' => 'courses',
'taxonomy' => 'courses-category',
'field' => 'term_id',
'terms' => $semester,
'meta_query' => array(
array(
'key' => 'course_number',
'value' => array( 100, 199 ),
'type' => 'numeric',
'compare' => 'BETWEEN'
)
),
'meta_key' => 'course_number',
'orderby' => 'meta_value_num',
'order' => 'ASC',
'posts_per_page' => '60'
);
$ud_query = new WP_Query($ud_args);
if($ud_query->have_posts()) : ?>
<h2 class="course-level-header">Undergraduate</h2>
<div class="courselist_content">
<?php while($ud_query->have_posts()) :
$ud_query->the_post(); ?>
<article id="post-<?php the_ID(); ?>" class="group course-list-wrapper">
<header class="index-header">
<h1 class="course-title">
<a href="<?php the_permalink(); ?>" title="<?php printf( esc_attr__( 'Permalink to %s', 'thales' ), the_title_attribute( 'echo=0' ) ); ?>" rel="bookmark">
<?php the_field('language_prefix'); ?> <?php the_field('course_number_prefix'); ?> <?php the_field('course_number'); ?><?php the_field('course_number_suffix'); ?>: <?php the_title(); ?>
</a>
</h1>
</header><!-- .entry-header -->
<div class="course-content">
<p class="section-spacing">
<?php the_field('timeframe'); ?> <span class="course-details"><?php the_field ('location'); ?></span>
<span class="course-details"><b>Instructor: <?php $post_object = get_field('instructor', $post->ID); ?> <a href="<?php echo get_permalink($post_object->ID); ?>"><?php echo $post_object->post_title; ?></a></p>
</b></span>
</p>
<?php the_content(__(' » read more »'));?>
<p class="section-spacing">Course Catalog Number: <?php the_field ('ccn'); ?></p>
</div><!-- .course-content -->
</article><!-- #post-<?php the_ID(); ?> -->
</div>
<?php endwhile; ?>
<?php endif; ?>
<?php wp_reset_query(); ?>
</div>
</section><!-- #content-container -->
</div>
</div>
<?php get_footer(); ?>
It depends on how you want the subfields to show up. Here’s an example if you want to show any subfields with certain value:
$rows = $wpdb->get_results($wpdb->prepare(
"
SELECT *
FROM {$wpdb->prefix}postmeta
WHERE
( meta_key LIKE %s AND meta_value = %s) OR
( meta_key LIKE %s AND meta_value = %s)
",
'colours_%_colour', 'red',
'images_%_type', 'type_3'
));
You can combine it with any keys and values you want. To learn more about the AND
and OR
syntax, please take a look at this page: http://www.hackingwithphp.com/9/3/13/multiple-where-conditions.
Also, I’m afraid this is a MySQL topic. For further support, please visit WordPress support forum or MySQL community instead.
Thanks 🙂
You’re Brilliant @hube2! This fixed it!
Here is a simplified version of how the code worked:
function update_sub_fields() {
global $wpdb; //declare using a global variable
$import_post_id = get_field('import_post'); //get the id of the post we are importing data from
if( have_rows('repeater_field_name') ): //start the repeater loop
while( have_rows('repeater_field_name') ): the_row();
$unique_id = get_sub_field('unique_id_field'); //get the unique id
$rows = $wpdb->get_results($wpdb->prepare(
"
SELECT *
FROM {$wpdb->prefix}postmeta
WHERE post_id = %s
AND meta_key LIKE %s
AND meta_value = %s
",
$import_post_id, //only look at meta-values that match the post we are importing from
'import_repeater_field_%_unique_id_field', // meta_name: $ParentName_$RowNumber_$ChildName
$unique_id // meta_value: to match our unique id
));
if( $rows ){
foreach( $rows as $row ){
preg_match('_([0-9]+)_', $row->meta_key, $matches);
$r = $matches[0];
$import_rows = get_field('import_repeater_field', $import_post_id);
$current_import_row = $import_rows[$r];
$sub_field_to_import = $current_import_row['sub_field_to_import'];
update_sub_field('new_field_to_update', $sub_field_to_import);
} //End foreach
} //End if
endwhile; //end loop
endif;
}
add_action( 'acf/imput/form_data', 'update_sub_fields', 10, 1);
I hope this helps anyone else who might be looking to import data from one repeater field to another!
Jess
Cool, so aside from the duplication, it seems to work fine as the goal is to redirect to the URL if a correct code is entered.
Code so far:
<?php
$codeErr = "";
$code = "";
if ($_SERVER["REQUEST_METHOD"] == "POST") {
if (empty($_POST["code"])) {
$codeErr = "<strong>Error:</strong> Promo code is required";
} else {
$code = code_input($_POST["code"]);
if (!preg_match("/[A-Za-z0-9]+/",$code)) {
$codeErr = "<strong>Error:</strong> Incorrect promo code. Please try again.";
} else {
$rows = $wpdb->get_results($wpdb->prepare(
"
SELECT *
FROM wp_vrtny1k0kz_postmeta
WHERE meta_key LIKE %s
AND meta_value = %s
",
'promosettings_%_code',
''.$code.''
));
if (!$rows){
$codeErr = "<strong>Error:</strong> Incorrect promo code. Please try again.";
}
}
}
}
function code_input($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
?>
<div class="row">
<div class="col-sm-6 col-xs-12">
<form action="<?php echo get_permalink(); ?>" method="post" id="promo">
<div class="row">
<div class="col-sm-9 col-xs-8">
<input type="text" name="code">
</div>
<div class="col-sm-3 col-xs-4">
<input type="submit" name="submit" value="Submit">
</div>
</div>
</form>
<span class="error"><?php echo $codeErr; ?></span>
</div>
</div>
<?php
if( $rows ) {
foreach( $rows as $row ) {
preg_match('_([0-9]+)_', $row->meta_key, $matches);
$url_key = 'promosettings_' . $matches[0] . '_url';
$url = get_post_meta( $row->post_id, $url_key, true );
?>
<script>
window.location.replace("<?php echo $url; ?>");
</script>
<?php
}
}
Edit – added a counter. Not sure if this is the most effective way, but it works
if( $rows ) {
$i = 0;
foreach( $rows as $row ) {
if($i == 0) {
preg_match('_([0-9]+)_', $row->meta_key, $matches);
$url_key = 'promosettings_' . $matches[0] . '_url';
$title_key = 'promosettings_' . $matches[0] . '_title';
$url = get_post_meta( $row->post_id, $url_key, true );
$title = get_post_meta( $row->post_id, $title_key, true );
echo $url;
echo $title;
}
$i++;
}
}
This is a code snippet from the cart.php file. Specifically for the table item named Product. How would I replace the woocommerce product title with an ACF field??? My logic is… if I can get a single field to show anywhere on the cart page, I should be able to figure out the rest on my own.
<?php
if ( ! $_product->is_visible() ) {
echo apply_filters( 'woocommerce_cart_item_name', $_product->get_title(), $cart_item, $cart_item_key ) . ' ';
} else {
echo apply_filters( 'woocommerce_cart_item_name', sprintf( '<a class="cart-link" href="%s">%s </a>', esc_url( $_product->get_permalink( $cart_item ) ), $_product->get_title() ), $cart_item, $cart_item_key );
}
// Meta data
echo WC()->cart->get_item_data( $cart_item );
// Backorder notification
if ( $_product->backorders_require_notification() && $_product->is_on_backorder( $cart_item['quantity'] ) ) {
echo '<p class="backorder_notification">' . esc_html__( 'Available on backorder', 'woocommerce' ) . '</p>';
}
?>
That works! thanks a bunch! Only problem: if there is no image, it throws a php error. Is there any way we can get the image conditionally, so that if the image field is empty it displays a default image (or nothing), instead of an error? My code now is this:
<?php
$values = get_field( 'execs','options' );
if ( $values ) {
$execs = array();
foreach ( $values as $value ) {
$link = get_author_posts_url( $value['ID'] ); //get the url
$nicename = $value['display_name'];
$userdesc = $value['user_description'];
$position = get_field( 'academic_position', 'user_' . $value['ID'] ); // custom ACF text
$affiliation = get_field( 'affiliations', 'user_' . $value['ID'] ); // custom ACF text
$pic_object = get_field( 'user_image', 'user_' . $value['ID'] );
$pic = '<img src="' . $pic_object['sizes']['thumbnail']. '" alt="' . $pic_object['alt'] . '" />';
$execs[] = sprintf( '<li><a href="%s">%s</a><p>%s</p><p>%s</p><p>%s</p>%s</li>', $link, $nicename, $userdesc, $position, $affiliation, $pic ); // listing
}
echo '<h4>Executive Committee</h4>';
echo '<ul>';
echo implode( $execs );
echo '</ul>';
}
?>
Hi @crabilld
Thanks for the bug report.
I’ve just found and fixed the issue.
Can you please edit the api/api-helpers.php file on line 3224 and change the if statement to:
// 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) );
}
}
This should allow uppercase file extensions to validate correctly.
Thanks
E
I have managed to work it out here is the answer if anyone needs it. This would go in your function.php file
// retrieves the attachment ID from the file URL
function get_image_id($image_url) {
global $wpdb;
$attachment = $wpdb->get_col($wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE guid='%s';", $image_url ));
return $attachment[0];
}
//Set the featured image on save of the post
add_action('save_post', 'set_featured_image_from_image');
//set featured image as main image.
function set_featured_image_from_image()
{
$has_thumbnail = get_the_post_thumbnail($post->ID);
//If there is not featured image get the other image.
if (!$has_thumbnail) {
//get the url of the ACF image and get the ID of that image
$image_url = get_field('main_image');
$image_id = get_image_id($image_url);
if ($image_id) {
set_post_thumbnail($post->ID, $image_id);
}
}
}
I am outputting just the url from the image so I had to reverse get the ID. Those who are using the full object should be able to get the ID more easily.
OK I finally solved this……..spent hours reading and trying things and finally figured out that I had to get the Post ID first, and make another change from the example I first found, so here is the code that WORKS, I’m posting it in case it might help anyone else trying to use a Repeater Field with values stored in wp_postmeta (not options as the example I found is) to populate a GravityForm dropdown, and needs to limit the values to the individual Post.
I added comments where needed, you can remove those if you use this.
// Replaces GravityForms dropdown with list of values from ACF Repeater field
add_filter("gform_pre_render_3", "dynamic_populate");
// replace '_3' with the actual ID from your Gravity Form, mine is form ID 3
function dynamic_populate($form) {
foreach($form['fields'] as &$field){
if(strpos($field['cssClass'], 'dynamicfield') === false)
continue;
//This only auto-populates a field which has the class dynamicfield. If it doesn't then, continue ! Don't forget to add a class to the field you want to dynamically populate in your form.
global $post;
$id = $post->ID; // Important - this is what tells the form to only use values from the individual post, not all posts
global $wpdb;
$rows = $wpdb->get_results($wpdb->prepare(
"
SELECT *
FROM wp_postmeta
WHERE post_id = %d AND meta_key LIKE %s
",
$id,
'room_types_%_room_type' //enter the actual name of your repeater field and sub-field names, the % is a variable that represents the row number
));
$choices = array(array('text' => 'Select Room Type', 'value' => ' '));
//Default choice for dynamic select field. Value is blank, so if it's required it won't validate, change the text to what you want it to be, e.g. 'Please Choose:'
if( $rows ){
foreach( $rows as $row ) {
//If there are results, for each result, find the 'repeater row number'
preg_match('_([0-9]+)_', $row->meta_key, $matches);
$meta_key = 'room_types_' . $matches[0] . '_room_type';
$value = get_post_meta($post->ID,$meta_key,true);
//Get the subfield value from the row.
$choices[] = array('text' => $value, 'value' => $value);
//Create an option array for each subfield value.
}
}
$field->choices = $choices;
//Once we've looped through all of the subfields values and created all of our options, we assign the $choices array (which has all of our new options) to the $field choices property.
}
return $form;
//Display the new dynamically populated form.
}
Oddly, I posted a followup post last night but it’s completely disappeared…..I still really need help with this please!
I’ve monkeyed around with the code a bit, and now I have it where it displays ALL the repeater field values from the wp_postmeta table, regardless of the Post they are attached to – this is NOT what I want. I want just the values associated with the Post I’m viewing, on which the GF form appears.
I have a Custom Post Type called “Resorts”, and on each Resort Page I have a repeater field to list the room types available for that resort (e.g. Deluxe, Suite, Oceanview, etc.). Each Resort has different room types.
On the (front end) Resort Page, I can display those room types just fine along with the rest of the resort info. ALSO on that Page is a (Gravity) Form for the site visitor to choose a room type and dates and get a price quote. The “room types” is a drop-down field that is supposed to auto-populate with the values from the repeater field.
SO the list of room types to choose from should be isolated to just that Resort – and it’s not, my drop down list is very long and includes ALL of the room types from ALL resorts…..aaargh!
I am NOT a coder, just trying to piece this together using examples from this website that don’t really fit – the examples are mostly for showing ALL field values, such as the “Diplay all images” example.
SO here is the code I’m using now – can someone PLEASE tell me how to modify this to ONLY show the repeater field values in the form dropdown from the one POST I’m viewing?
add_filter("gform_pre_render_3", "dynamic_populate");
function dynamic_populate($form) {
foreach($form['fields'] as &$field){
if(strpos($field['cssClass'], 'dynamicfield') === false)
continue;
//Condition : each field which has the class dynamicfield (example). If it doesn't then, continue ! Don't forget to add a class to the field you want to dynamically populate in your form.
global $wpdb;
$rows = $wpdb->get_results($wpdb->prepare(
"
SELECT *
FROM wp_postmeta
WHERE meta_key LIKE %s
",
'room_types_%_room_type'
));
$choices = array(array('text' => 'Select Room Type', 'value' => ' '));
//Default choice for dynamic select field. Value is blank, so if it's required it won't validate.
if( $rows ){
foreach( $rows as $row ) {
//If there are results, for each result, find the 'repeater row number'
preg_match('_([0-9]+)_', $row->meta_key, $matches);
$meta_key = 'room_types_' . $matches[0] . '_room_type';
$value = get_post_meta( $row->post_id, $meta_key, true );
//Get the subfield value from the row.
$choices[] = array('text' => $value, 'value' => $value);
//Create an option array for each subfield value.
}
}
$field->choices = $choices;
//Once we've looped through all of the subfields values and created all of our options, we assign the $choices array (which has all of our new options) to the $field choices property.
}
return $form;
//Display the new dynamically populated form.
}
<?php
$args = array(
'taxonomy' => 'sock-club',
'hide_empty' => '0'
);
$terms = get_terms('sock-club', $args);
if ($terms) {
foreach ($terms as $index => $term) {
$terms[$index]->star_rating = get_field('star_rating', $taxonomy.'_'$term_id);
}
usort($terms, 'my_sort_function');
// create the list after the terms are sorted
// need to loop through them again
$term_list = '';
foreach ($terms as $term) {
$term_list .= '<a href="' . get_term_link( $term ) . '" title="' . sprintf( __( 'View all post filed under %s', 'my_localization_domain' ), $term->name ) . '">' . $term->name . '</a>';
}
}
?>
Thank you John,
As a beginner I am still not able to get it working this way. This is the code I have:
In my functions.php file:
function my_sort_function($a, $b) {
if ($a->star_rating == $b->star_rating) {
return 0;
} elseif ($a->star_rating < $b->star_rating) {
return -1;
} else {
return 1;
}
}
On my home page:
<?php
$args = array(
'taxonomy' => 'sock-club',
'hide_empty' => '0'
);
$terms = get_terms('sock-club', $args);
if ($terms) {
foreach ($terms as $index => $term) {
$terms[$index]->star_rating = get_field('star_rating', $taxonomy.'_'$term_id);
$term_list .= '<a href="' . get_term_link( $term ) . '" title="' . sprintf( __( 'View all post filed under %s', 'my_localization_domain' ), $term->name ) . '">' . $term->name . '</a>';
}
usort($terms, 'my_sort_function');
}
?>
Can you see what is wrong with my code?
This went faster than I thought. I basically had to copy/paste those codes you linked to.
Here’s what I did:
function get_custom_values( $key = 'YOUR_FIELD', $type = 'post', $status = 'publish' ) {
global $wpdb;
if( empty( $key ) )
return;
$custom_arry = $wpdb->get_col( $wpdb->prepare( "
SELECT pm.meta_value FROM {$wpdb->postmeta} pm
LEFT JOIN {$wpdb->posts} p ON p.ID = pm.post_id
WHERE pm.meta_key = '%s'
AND p.post_status = '%s'
AND p.post_type = '%s'
", $key, $status, $type ) );
foreach ($custom_arry as $custom_field) {
$custom_result.= $custom_field. "SEPARATION_SIGN";
}
return $custom_result;
}
$fina_custom_result = get_custom_values();
If it helps anyone, I put together this function for ACF 4 to get the correct field key for a given post and field name to match:
/**
* Get field key for field name. ACF 4
* Will return first matched acf field key for a given field name to match.
*
* This function will return the field_key of a certain field.
*
* @param $post_id int The post id to check.
* @param $field_match String The field name to match in the query in SQL format e.g. '%versions%'
* @return
*/
private function acf_get_field_key( $post_id, $field_match ) {
global $wpdb;
$posts = $wpdb->get_results( $wpdb->prepare( "SELECT ID FROM $wpdb->posts where post_type=%s", 'acf' ) );
$rows = $wpdb->get_results( $wpdb->prepare("SELECT meta_key,meta_value FROM $wpdb->postmeta WHERE post_id = %d AND meta_key LIKE %s AND meta_value LIKE %s", $posts[0]->ID, 'field_%', $field_match), ARRAY_A);
$field_data = unserialize( $rows[0]["meta_value"] );//not sure why it is in there twice...
return $field_data['key'];
}
ok: i’ve come this far.
I used the script for Querying the database for repeater sub field values. I deleted the meta_value part because i dont have a meta value, i only have the thumbnails (the value is the path to the thumbnail). So it should view all images used in the sub field thumbnail in the repeater gallery_repeat.
It shows all images, but in multiple numbers.. (it shows the one repeater 3 times, the other one 5 times, …)
this is my code: (source: http://www.advancedcustomfields.com/resources/querying-the-database-for-repeater-sub-field-values/ )
<?php
// get all rows from the postmeta table where the sub_field (type) equals 'type_3'
// - http://codex.wordpress.org/Class_Reference/wpdb#SELECT_Generic_Results
$rows = $wpdb->get_results($wpdb->prepare(
"
SELECT *
FROM wp_postmeta
WHERE meta_key LIKE %s
",
'gallery_repeat_%_thumbnail' // meta_name: $ParentName_$RowNumber_$ChildName
));
// loop through the results
if( $rows )
{
foreach( $rows as $row )
{
// for each result, find the 'repeater row number' and use it to load the image sub field!
preg_match('_([0-9]+)_', $row->meta_key, $matches);
$meta_key = 'gallery_repeat_' . $matches[0] . '_thumbnail'; // $matches[0] contains the row number!
// use get_post_meta to load the image sub field
// - http://codex.wordpress.org/Function_Reference/get_post_meta
$image_id = get_post_meta( $row->post_id, $meta_key, true );
// load image src
// - http://www.advancedcustomfields.com/resources/field-types/image/
$src = wp_get_attachment_image_src( $image_id, 'full' );
?>
<div class="item">
<img src="<?php echo $src[0]; ?>" />
<p class="wp-caption-text">From
<a href="<?php get_permalink( $row->post_id ); ?>">
<?php echo get_the_title( $row->post_id ); ?>
</a>
</p>
</div>
<?php
}
}
?>
and a screenshot to show how it looks now:
As you can see, it shows multiple identical images. in my thumbnails theres only one per repeater (all unique).
It looks like it should be an easy fix, but my knowledge does not reach this far. Would help me out greatly if this was resolved!
edit: ive noticed that everytime i edit the post, a dublicate of the image is made for some reason…
regards,
Mathieu
Wouldn’t that mean hard coding these field keys into my code?
In the meantime I ended up querying the database like this:
function get_field_label( $field, $value ) {
global $wpdb;
$label = '';
$field = $wpdb->get_col( $wpdb->prepare( "
SELECT post_content FROM {$wpdb->posts}
WHERE post_excerpt = '%s'
AND post_type = 'acf-field'
", $field ) );
if( $field ) {
$options = unserialize( $field[0] );
$choices = $options['choices'];
$label = $choices[$value];
}
return $label;
}
I have no idea if this will help in your situation, but I solved mine by using $wpdb->get_results
. In my particular situation, I had a repeater of “Questions”. Each question had a text field “Question”, and a dropdown which is supposed to display the other items in the repeater.
This code pulls the “question” field for each “questions” on the current post, and since it’s done directly through the $wpdb
query it doesn’t trigger any of the ACF actions or filters, avoiding the infinite loop.
function loadQuestions($field) {
global $wpdb;
$field['choices'] = array( 0 => 'None' );
$choices = $wpdb->get_results($wpdb->prepare(
"SELECT meta_value FROM wp_postmeta WHERE post_id = %d AND meta_key RLIKE %s",
get_the_id(),
sprintf('^%s_[0-9]*_%s$', 'questions', 'question')
), ARRAY_A);
for ($i = 0; $i < count($choices); $i++) {
$field['choices'][] = $choices[$i]['meta_value'];
}
return $field;
}
This isn’t a perfect solution — my number one issue with it is that it only pulls values that have already been saved in the database, so in my situation, I have to save all the questions before I can set any of the dropdowns. I’m 90% sure this could be solved with a little javascript, but I haven’t had the time to investigate further, and it’s not important enough on my end to warrant the time.
Figured it out on my own. Putting this here in case it helps someone. The following uses both a repeater field and flexible content in the widget.
function my_dynamic_sidebar_params( $params ) {
// get widget vars
$widget_name = $params[0]['widget_name'];
$widget_id = $params[0]['widget_id'];
// bail early if this widget is not a Text widget
if( $widget_name != 'Text' ) {
return $params;
}
//add content to widget
$content_type = get_field('content_type', 'widget_' . $widget_id);
if( $content_type == 'important_links' ) {
?>
<?php $params[0]['after_title'] .= '<ul>' ?>
<?php while(the_flexible_field("important_links", 'widget_' . $widget_id)): ?>
<?php if(get_row_layout() == "file"): // layout: file
//vars
$file_link_text = get_sub_field('file_link_text', 'widget_' . $widget_id);
$file = get_sub_field('file', 'widget_' . $widget_id);
$file_type = get_sub_field('file_type', 'widget_' . $widget_id);
?>
<?php $params[0]['after_title'] .= sprintf('<li><a href="%s" class="is-%s">%s</a></li>', $file['url'], $file_type, $file_link_text) ?>
<?php elseif(get_row_layout() == "link"): // layout: link
$link_text = get_sub_field('link_text', 'widget_' . $widget_id);
$url = get_sub_field('url', 'widget_' . $widget_id);
?>
<?php $params[0]['after_title'] .= sprintf('<li><a href="%s">%s</a></li>', $url, $link_text) ?>
<?php endif; ?>
<?php endwhile; ?>
<?php $params[0]['after_title'] .= '</ul>' ?>
<?php }
if( $content_type == 'contacts' ) { ?>
<?php if( have_rows('contacts', 'widget_' . $widget_id) ): ?>
<?php $params[0]['after_title'] .= '<ul>' ?>
<?php while( have_rows('contacts', 'widget_' . $widget_id) ): the_row();
// vars
$contact_name = get_sub_field('contact_name', 'widget_' . $widget_id);
$contact_title = get_sub_field('contact_title', 'widget_' . $widget_id);
$contact_phone = get_sub_field('contact_phone', 'widget_' . $widget_id);
$contact_email = get_sub_field('contact_email', 'widget_' . $widget_id);
$tel = preg_replace("/[^A-Za-z0-9]/", "", $contact_phone);
?>
<?php $params[0]['after_title'] .= sprintf('<li><header><h4>%s</h4>', $contact_name) ?>
<?php $params[0]['after_title'] .= sprintf('<h5>%s</h5></header><p>', $contact_title) ?>
<?php $params[0]['after_title'] .= sprintf('<a class="tel" href="tel:%s">%s</a><br />', $tel, $contact_phone) ?>
<?php $params[0]['after_title'] .= sprintf('<a class="email" href="mailto:%s">%s</a></p></li>', $contact_email, $contact_email) ?>
<?php endwhile; ?>
<?php $params[0]['after_title'] .= '</ul>' ?>
<?php endif;
}
// return
return $params;
}
add_filter('dynamic_sidebar_params', 'my_dynamic_sidebar_params');
Actually, ACF does not handle the %s and printf stuff internally.
If we break it down to steps:
Thanks a lot Hube2! That worked, I just needed to add the option-call and all is fine:
printf(get_field('my-ACF-field-value', 'option'), get_the_title($post->post_parent));
I thought ACF probably didn’t use %s and this wouldn’t be possible, but I’m happy I was wrong. Amazing plugin, I am continuously impressed the more I learn about it.
Welcome to the Advanced Custom Fields community forum.
Browse through ideas, snippets of code, questions and answers between fellow ACF users
Helping others is a great way to earn karma, gain badges and help ACF development!
We use cookies to offer you a better browsing experience, analyze site traffic and personalize content. Read about how we use cookies and how you can control them in our Privacy Policy. If you continue to use this site, you consent to our use of cookies.