You have to use a front end form. The documentation is here.
Basically, you change the settings below to fit your needs and add the acf_form($settings); where you want the form to appear.
It involves programming, so you have to have access to the WordPress theme files.
If you want this to appear on the Edit-tours.php page you have to add the coding to that file.
This: <?php acf_form_head(); ?> goes at the top of your file ahead of get_header();.
$settings = array(
/* (string) Unique identifier for the form. Defaults to 'acf-form' */
'id' => 'acf-form',
/* (int|string) The post ID to load data from and save data to. Defaults to the current post ID.
Can also be set to 'new_post' to create a new post on submit */
'post_id' => false,
/* (array) An array of post data used to create a post. See wp_insert_post for available parameters.
The above 'post_id' setting must contain a value of 'new_post' */
'new_post' => false,
/* (array) An array of field group IDs/keys to override the fields displayed in this form */
'field_groups' => false,
/* (array) An array of field IDs/keys to override the fields displayed in this form */
'fields' => false,
/* (boolean) Whether or not to show the post title text field. Defaults to false */
'post_title' => false,
/* (boolean) Whether or not to show the post content editor field. Defaults to false */
'post_content' => false,
/* (boolean) Whether or not to create a form element. Useful when a adding to an existing form. Defaults to true */
'form' => true,
/* (array) An array or HTML attributes for the form element */
'form_attributes' => array(),
/* (string) The URL to be redirected to after the form is submit. Defaults to the current URL with a GET parameter '?updated=true'.
A special placeholder '%post_url%' will be converted to post's permalink (handy if creating a new post)
A special placeholder '%post_id%' will be converted to post's ID (handy if creating a new post) */
'return' => '',
/* (string) Extra HTML to add before the fields */
'html_before_fields' => '',
/* (string) Extra HTML to add after the fields */
'html_after_fields' => '',
/* (string) The text displayed on the submit button */
'submit_value' => __("Update", 'acf'),
/* (string) A message displayed above the form after being redirected. Can also be set to false for no message */
'updated_message' => __("Post updated", 'acf'),
/* (string) Determines where field labels are places in relation to fields. Defaults to 'top'.
Choices of 'top' (Above fields) or 'left' (Beside fields) */
'label_placement' => 'top',
/* (string) Determines where field instructions are places in relation to fields. Defaults to 'label'.
Choices of 'label' (Below labels) or 'field' (Below fields) */
'instruction_placement' => 'label',
/* (string) Determines element used to wrap a field. Defaults to 'div'
Choices of 'div', 'tr', 'td', 'ul', 'ol', 'dl' */
'field_el' => 'div',
/* (string) Whether to use the WP uploader or a basic input for image and file fields. Defaults to 'wp'
Choices of 'wp' or 'basic'. Added in v5.2.4 */
'uploader' => 'wp',
/* (boolean) Whether to include a hidden input field to capture non human form submission. Defaults to true. Added in v5.3.4 */
'honeypot' => true,
/* (string) HTML used to render the updated message. Added in v5.5.10 */
'html_updated_message' => '<div id="message" class="updated"><p>%s</p></div>',
/* (string) HTML used to render the submit button. Added in v5.5.10 */
'html_submit_button' => '<input type="submit" class="acf-button button button-primary button-large" value="%s" />',
/* (string) HTML used to render the submit button loading spinner. Added in v5.5.10 */
'html_submit_spinner' => '<span class="acf-spinner"></span>',
/* (boolean) Whether or not to sanitize all $_POST data with the wp_kses_post() function. Defaults to true. Added in v5.6.5 */
'kses' => true
);
acf_form($settings);
Alright, thanks for confirming this. I may get into some custom JavaScript at some point, but this particular field is mostly read-only, and for now can be set when saving the post.
For future readers, I ended up making the field read-only when set to null, and then hooking into update_value to generate unique values there. I set the placeholder text to “Automatically generated on save”. Not the most elegant solution, but it works!
function my_acf_generate_file_url($value, $post_id, $field) {
if ($value == NULL) {
// generate GUID unique to each row of the repeater and it's value
$data = openssl_random_pseudo_bytes(16);
$data[6] = chr(ord($data[6]) & 0x0f | 0x40); // set version to 0100
$data[8] = chr(ord($data[8]) & 0x3f | 0x80); // set bits 6-7 to 10
$value = vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
}
return $value;
}
add_filter('acf/update_value/key=field_xxxxxxxx', 'my_acf_generate_file_url', 10, 3);
G’day Mate,
the function get_queried_object
is getting the current object. So, on a archive page, the current object is the current taxonomy term. However, on the single, it is the current post. That’s why acf couldn’t return the value unless you tell it to get it from the taxonomy.
On line 192, where the theme is using get_the_term_list
to build the category list. However, if you want to apply custom class to it, you’d need to construct the html output yourself.
So, you should update that section to look like:
if(!empty($taxonomies))
{
foreach($taxonomies as $taxonomy)
{
if(!in_array($taxonomy, $excluded_taxonomies))
{
// get all the terms in this taxonomy
$terms = get_the_terms(null, $taxonomy)? : [];
foreach ($terms as $term) {
// loop through them, and add the color as style attribute
$cats .= sprintf(
'<a href="%s" style="color: %s">%s</a>',
get_term_link($term),
get_field('color', $term),
$term->name
);
}
}
}
}
Cheers
Nevermind just figured it out, I nested the forloops
Heres my code if it helps someone else, just trying to stop it from returning values that dont relate to the current post:
function acf_event_cost_options( $form ){
foreach ($form['fields'] as &$field) {
if(strpos($field->cssClass, 'acf_event_cost_options') === 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_name = $wpdb->get_results($wpdb->prepare(
"
SELECT *
FROM wp_postmeta
WHERE post_id = %d AND meta_key LIKE %s
",
$id,
'event_cost_structure_%_option_name' //enter the actual name of your repeater field and sub-field names, the % is a variable that represents the row number
));
$rows_price = $wpdb->get_results($wpdb->prepare(
"
SELECT *
FROM wp_postmeta
WHERE post_id = %d AND meta_key LIKE %s
",
$id,
'event_cost_structure_%_option_price' //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' => 'Please Choose an Option', 'value' => ' ', 'price' => ' '));
//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_name || $rows_price ) {
foreach ($rows_name as $row_name) {
foreach ($rows_price as $row_price) {
//If there are results, for each result, find the 'repeater row number'
preg_match('_([0-9]+)_', $row_name->meta_key, $matches);
$meta_key = 'event_cost_structure_' . $matches[0] . '_option_name';
$value = get_post_meta($post->ID, $meta_key, true);
//Get the subfield value from the row.
//If there are results, for each result, find the 'repeater row number'
preg_match('_([0-9]+)_', $row_price->meta_key, $matches);
$meta_key_price = 'event_cost_structure_' . $matches[0] . '_option_price';
$value_price = get_post_meta($post->ID, $meta_key_price, true);
//Get the subfield value from the row.
$choices[] = array('text' => $value . ' $' . $value_price . '.00', 'value' => $value, 'price' => $value_price);
//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.
}
I only use it to ‘upvote’ FAQ posts, not downvote, so only the upvote part is here but I think you get the idea and can create the downvote, based of this. Plus the output is written in twig instead of php but that’s not an issue I think.
Code in template (code is as is)
<div class="faq__helpful">
<h4>{{ __( 'Was this helpful', 'textdomain' ) }} ?</h4>
<div>
<form class="faq_helpful" action="" method="post">
<input type="hidden" name="post_id" value="{{ post.ID }}" />
<input type="hidden" name="sd_faq__nonce" value="{{ function( 'wp_create_nonce', 'sd-faq-nonce' ) }}" />
<button type="submit" name="helpful_yes" value="1" class="button item__delete-submit">
{{ __( 'YES', 'textdomain' ) }}
</button>
{% if helpful_yes %}
<small>{{ _n( '%s person found this helpful', '%s people found this helpful', helpful_yes, 'textdomain')|format(helpful_yes) }}</small>
{% endif %}
</form>
</div>
</div>
if ( isset( $_POST[ "sd_faq__nonce" ] ) ) {
if ( wp_verify_nonce( $_POST[ "sd_faq__nonce" ], 'sd-faq-nonce' ) ) {
// add helpful counter
if ( isset( $_POST[ "helpful_yes" ] ) && '1' == $_POST[ "helpful_yes" ] ) {
$faq_id = get_the_ID();
if ( $hf_yes == false ) {
update_post_meta( $faq_id, 'sd_helpful_yes', '1' );
} else {
$hf_yes = $hf_yes + 1;
update_post_meta( $faq_id, 'sd_helpful_yes', $hf_yes );
}
}
}
}
Since this is not an ACF issue/topic I don’t wanna get too deep into this. WordPress.stackexchange.com is a better place for all WP questions.
Hi,
What I mean by the $_POST['tri']
is that, your form output is looking something like this:
<form action="..." method="POST" class="user-email-settings">
<div class="user">
<input type="checkbox" id="1" name="1" class="pref" value="1" checked /> first last
</div>
<div class="user">
<input type="checkbox" id="2" name="2" class="pref" value="1" /> first last
</div>
...
<input type="submit" value="Update Tri Annual Status" name="status" id="status" class="ai-button" />
</form>
None of the input contains the name ‘tri’. Therefor your $_POST
will only contains:
$_POST = [
1 => 1,
'status' => 'Update Tri Annual Status'
];
1) the name of the checkbox input is the index in the $_POST variable.
2) if the checkbox is not check, the $_POST variable will not include them.
—————————————————————————
Based on my understanding of your code, i think what you want is something like the following:
if (has_some_permission()):
$users = do_something_to_get_those_users();
if ($_POST['status']) {
foreach ($users as $user) {
update_field('field_598c6559e1b0d', $_POST['tri'][$user->ID], $user);
}
echo '<p class="success">Status Updated<p>';
}
echo '<h2 class="group-table-heading">Tri Annual Status</h2>';
echo '<form action="' . get_the_permalink() . '" method="POST" class="user-email-settings">';
foreach ($users as $user) {
$f = get_user_meta($user->ID, 'first_name', true);
$l = get_user_meta($user->ID, 'last_name', true);
$field = get_user_meta($user->ID, 'tri', true);
// is this an acf field?
// $field = get_field('field_598c6559e1b0d', $user);
// $field = get_field('tri', $user);
echo '<div class="user">';
echo sprintf('<input type="hidden" name="tri[%d]" value="0" />', $user->ID);
echo sprintf('<input type="checkbox" name="tri[%d]" value="1" %s />', $user->ID, $field? 'checked' : '');
echo " {$f} {$l}";
echo '</div>';
}
echo '<input type="submit" value="Update Tri Annual Status" name="status" id="status" class="ai-button" />';
echo '</form>';
}
Notice the checkbox’s name attribute is what will get put into the $_POST
variable.
The $_POST variable after this form is submitted will be something like:
$_POST = [
'tri' => [
1 => 1,
2 => 0,
3 => 0,
4 => 0
],
'status' => 'Update Tri Annual Status'
];
Cheers
Hi. I have done something similar. I added a field to regular posts where a user can be selected. This is used to ‘mention’ a certain user. On their profile I retrieve the posts again in which they got mentioned.
See https://internationaldownhillfederation.org/member/emily-pross/
Halfway down. User is mentioned in these posts.
What you’re looking at is an author.php archive so this is a separate query because a user is mentioned in those posts, they didn’t write it.
My profile shows both mentioned and posts I wrote.
So here we go 🙂
First of all, Can you add only 1 user per post ??? Looks like it (I can be wrong). Why not make a repeater out of that field with 1 sub field; which is user.
My field is called tagged_riders.
This is a repeater with 1 sub-field (member).
Member is a user object field.
/**
* Get posts in which user is mentioned
* @param bool $user_id
*
* @return bool|array
*/
function get_user_mentions( $user_id = false ) {
if ( false == $user_id ) {
return false;
}
global $wpdb;
$rows = $wpdb->get_results( $wpdb->prepare(
"
SELECT *
FROM {$wpdb->prefix}postmeta
WHERE meta_key LIKE %s
AND meta_value = %s
", 'tagged_riders_%_member', // meta_name: $ParentName_$RowNumber_$ChildName
$user_id ) );
if ( $rows ) {
$post_ids = array();
foreach ( $rows as $row ) {
$post_ids[] = intval( $row->post_id );
}
return $post_ids;
}
return false;
}
Keep in mind my fields are called tagged_riders with a subfield member. You need to change these to fit your needs.
Get all post_ids like this: get_user_mentions( $user_id ), where $user_id is the ID you want to check.
The results is an array of post_ids in which the user liked.
Hope this helps.
Hi
There’s filter on the relationship field that you can change how the title showed up.
https://www.advancedcustomfields.com/resources/acf-fields-relationship-result/
How the relationship field interface works is, it just copy the text from the left side to right side. So you’d need to do some css to hide the edit link on the left.
Here’s the filter code looks like:
add_filter('acf/fields/relationship/result', 'acf_append_edit_link_to_relationship_results', 10, 4);
function acf_append_edit_link_to_relationship_results($title, $post, $field, $post_id) {
$title .= sprintf('<a href="%s" target="_blank">%s</a>', get_edit_post_link($post_id), __('Edit'));
return $title;
}
Cheers. 😜
add_shortcode’s callback accepts 2 parameters. The first one being the attributes and the second on is the body content. https://developer.wordpress.org/reference/functions/add_shortcode/
Then you can use php’s array_slice to to slice the array with a starting index and length. http://php.net/manual/en/function.array-slice.php
So, you callback will look something like this:
function allphotos_shortcode($attrs) {
$attrs = shortcode_atts([
'start' => 0,
'number' => null,
], $attrs);
if (! $images = get_field('fl_gallery')) {
return '';
}
if (! $images = array_slice($images , $attrs['start'], $attrs['number'])) {
return '';
}
$output .= '<ul id="kalpht">';
foreach ($images as $image) {
$output .= sprintf(
'<li><a class="x-img-link" href="%s" data-options="%s">%s</a></li>',
$image['url'],
"thumbnail:'{$image['sizes']['mini-me']}'",
wp_get_attachment_image($image['id'], 'mini-me')
);
}
$output .= '</ul>' . do_shortcode('[lightbox opacity="0.9" thumbnails="true"]');
return $output;
}
cheers
Thank’s for answering.
Hell Yes ! It sounds obvious but this does not retreive anything (empty result) …
This is the full code :
global $wpdb;
$prefix =$wpdb->prefix;
$tablename = $prefix."postmeta";
$sql = "SELECT * FROM {$tablename} WHERE meta_key LIKE %s GROUP BY meta_key";
$iconbox_contents = $wpdb->get_results( $wpdb->prepare( $sql, '_jst_iconbox_%_iconbox_content' ) );
if( $iconbox_contents )
{
foreach( $iconbox_contents as $boxcontent )
{
$field = get_field_object( $boxcontent->meta_key, get_the_ID() );
echo '<pre>'.print_r( $field, 1) .'</pre><hr>';//now this is empty
}
}
Still stuck with this…
The code is located on the file “content.php” of the theme Stargazer. I can’t found a standard function. The complete code is presented bellow:
<article <?php hybrid_attr( 'post' ); ?>>
<?php if ( is_singular( get_post_type() ) ) : // If viewing a single post. ?>
<header class="entry-header">
<h1 <?php hybrid_attr( 'entry-title' ); ?>><?php single_post_title(); ?></h1>
<div class="entry-byline">
<span <?php hybrid_attr( 'entry-author' ); ?>><?php the_author_posts_link(); ?></span>
<time <?php hybrid_attr( 'entry-published' ); ?>><?php echo get_the_date(); ?></time>
<?php comments_popup_link( number_format_i18n( 0 ), number_format_i18n( 1 ), '%', 'comments-link', '' ); ?>
<?php if ( function_exists( 'ev_post_views' ) ) ev_post_views( array( 'text' => '%s' ) ); ?>
<?php edit_post_link(); ?>
</div><!-- .entry-byline -->
<!-- MOSTRAR CAMPOS PERSONALIZADOS -->
<!-- Documento principal -->
<?php
$attachment_id = get_field('archivo');
$url = wp_get_attachment_url($attachment_id);
$title = get_the_title($attachment_id);
$path_info = pathinfo(get_attached_file($attachment_id));
$filesize = filesize( get_attached_file( $attachment_id ) );
$filesize = size_format($filesize, 2);
if(get_field('archivo')): ?>
<div class="titulos_secundarios">Ver documento:</div><br/><br/>
<a href="<?php echo $url; ?>" target="_blank" title="Abrir documento en una nueva pestaña" style="display: inline;"><?php echo $title?>.<?php echo $path_info['extension'];?> (<?php echo $filesize; ?>)</a>
<?php
endif;
?>
<!-- Documentos secundarios -->
<br/>
<div class="titulos_secundarios">Antecedentes</div>
<br/>
<?php if(have_rows('otros_archivos')):
while (have_rows('otros_archivos')) : the_row();
$post_object = get_sub_field('antecedente');
echo "<ol>";
if($post_object):
$post = $post_object; setup_postdata($post); ?>
<li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
<?php wp_reset_postdata();
else:
echo "<li>No se ha incluido ningún antecedente aún.</li><br/>";
endif;
echo "</ol>";
endwhile;
endif; ?>
<!-- FIN MOSTRAR CAMPOS PERSONALIZADOS -->
</header><!-- .entry-header -->
<div <?php hybrid_attr( 'entry-content' ); ?>>
<?php the_content(); ?>
<?php wp_link_pages(); ?>
</div><!-- .entry-content -->
<footer class="entry-footer">
<?php hybrid_post_terms( array( 'taxonomy' => 'category', 'text' => __( 'Posted in %s', 'stargazer' ) ) ); ?>
<?php hybrid_post_terms( array( 'taxonomy' => 'post_tag', 'text' => __( 'Tagged %s', 'stargazer' ), 'before' => '<br />' ) ); ?>
</footer><!-- .entry-footer -->
<?php else : // If not viewing a single post. ?>
<?php get_the_image( array( 'size' => 'stargazer-full', 'order' => array( 'featured', 'attachment' ) ) ); ?>
<header class="entry-header">
<?php the_title( '<h2 ' . hybrid_get_attr( 'entry-title' ) . '><a href="' . get_permalink() . '" rel="bookmark" itemprop="url">', '</a></h2>' ); ?>
<div class="entry-byline">
<span <?php hybrid_attr( 'entry-author' ); ?>><?php the_author_posts_link(); ?></span>
<time <?php hybrid_attr( 'entry-published' ); ?>><?php echo get_the_date(); ?></time>
<?php comments_popup_link( number_format_i18n( 0 ), number_format_i18n( 1 ), '%', 'comments-link', '' ); ?>
<?php edit_post_link(); ?>
</div><!-- .entry-byline -->
</header><!-- .entry-header -->
<div <?php hybrid_attr( 'entry-summary' ); ?>>
<?php the_excerpt(); ?>
</div><!-- .entry-summary -->
<?php endif; // End single post check. ?>
</article><!-- .entry -->
So I actually went with $wpdb
because I can combine that with some additional requirements I had. Here’s the query I ended up with:
$category_slug = $_GET["category"];
if($category_slug) {
$category_query = $wpdb->prepare("AND wp_terms.slug = %s", $category_slug);
} else {
$category_query = "";
}
$event_dates_query = <<<EOD
SELECT event_dates.*, $wpdb->terms.name AS category_name
FROM $wpdb->posts AS event_dates
INNER JOIN $wpdb->postmeta AS acf_event
ON acf_event.meta_key = 'event'
AND acf_event.post_id = event_dates.ID
INNER JOIN $wpdb->postmeta AS acf_date
ON acf_date.meta_key = 'date'
AND acf_date.post_id = event_dates.ID
INNER JOIN $wpdb->posts AS events
ON events.ID = acf_event.meta_value
INNER JOIN $wpdb->term_relationships
ON $wpdb->term_relationships.object_id = events.ID
INNER JOIN $wpdb->term_taxonomy
ON $wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id
INNER JOIN $wpdb->terms
ON $wpdb->term_taxonomy.term_id = wp_terms.term_id
WHERE (acf_date.meta_value >= %s
AND acf_date.meta_value < %s)
AND event_dates.post_type = 'event_date'
AND event_dates.post_status = 'publish'
$category_query
GROUP BY event_dates.ID
ORDER BY acf_date.meta_value ASC;
EOD;
$event_dates = $wpdb->get_results(
$wpdb->prepare($event_dates_query,
$first_day_of_month,
$last_day_of_month));
Besides joining various term-taxonomy-meta-tables I also filter the EventDate
s by their date, so I can paginate them by month.
So there’s quiet an ugly query sitting in my template now, but I think in terms of performance and lines of (php) code written that’s the best I can hope for here.
Based on this query I was also able to build a fulltext search where I query for attributes and meta-keys of Event
s and get back their related EventDate
s quiet easily, so thats nice too.
Just a comment for people looking for anything similar. Please not that I am not the developer of ACF or do I have first hand knowledge of the module mentioned in the OP.
The main problem with when things that combine scripts into a single file break a site is that they fail to take into account the use of localizing scripts in WP. Many plugins, including ACF rely on this localization to work.
When a script is localized WP adds something similar to this just before the line that loads the JS file
<script type="text/javascript">
/* <![CDATA[ */
var adminCommentsL10n = {"hotkeys_highlight_first":"","hotkeys_highlight_last":"","replyApprove":"Approve and Reply","reply":"Reply","warnQuickEdit":"Are you sure you want to edit this comment?\nThe changes you made will be lost.","warnCommentChanges":"Are you sure you want to do this?\nThe comment changes you made will be lost.","docTitleComments":"Comments","docTitleCommentsCount":"Comments (%s)"};
/* ]]> */
</script>
The above is a WP localization for /wp-admin/js/edit-comments.js
This localized data must appear before the effected script is included in many cases because the script depends on these values to work properly.
In other cases the combination does take this into account but it will minify this example code to a single line, which will also break the code because the CDATA tags need to be their own separate lines.
Another thing that could break sites is that a tiny error in one JS file, when minified, could cause an error that breaks all of the scripts that are included after it.
Hi @hube2
Thanks aganin!
In the end, I made this sa a solution.
(very rough code though…)
function my_get_field_object_for_new_post($selector, $parent_selector = ''){
global $wpdb;
$where = '';
$parent_id = false;
$result_key = false;
if($parent_selector != ''){
$sql = "SELECT ID FROM $wpdb->posts WHERE post_excerpt = %s AND post_type = 'acf-field'";
$sql = $wpdb->prepare($sql, $parent_selector);
$result = $wpdb->get_row( $sql );
if((int)$result->ID > 0){
$parent_id = $result->ID;
}
else {
$sql = "SELECT ID FROM $wpdb->posts WHERE post_title = %s AND post_type = 'acf-field-group'";// can be group name
$sql = $wpdb->prepare($sql, $parent_selector);
$result = $wpdb->get_row( $sql );
if((int)$result->ID > 0){
$parent_id = $result->ID;
}
}
if($parent_id){
$where = " AND <code>post_parent</code> = " . $parent_id;
}
}
if($selector!=''){
$sql = "SELECT post_name FROM $wpdb->posts WHERE post_excerpt = %s AND post_type = 'acf-field'".$where;
$sql = $wpdb->prepare($sql, $selector);
$result = $wpdb->get_row( $sql );
if( $result->post_name ){
$result_key = $result->post_name;
}
}
return $result_key;
}
Hi @decay
Thank you for the examples. I want to note that you’re setting a $h3
variable inside the if statement that’s not being used in the example.
So for anyone looking to use this you do not need that. Here’s a cleaned up example:
if( get_sub_field( 'fieldname/fieldkey' ) ){
echo sprintf( '<h3>%s</h3>', $title );
} else {
echo sprintf( '<h2>%s</h2>', $title );
}
And a shorthand version:
echo ( get_sub_field( 'fieldname/fieldkey' ) ? sprintf( '<h3>%s</h3>', $title ) : sprintf( '<h2>%s</h2>', $title ) );
Hi James @acf-support,
Great! Nearly there. How do I go about including both the Title and Content sub fields in the SQL? The example only shows for one sub field.
"
SELECT *
FROM {$wpdb->prefix}postmeta
WHERE meta_key LIKE %s
AND meta_value = %s
",
'images_%_type', // meta_name: $ParentName_$RowNumber_$ChildName
'type_3' // meta_value: 'type_3' for example
Hi @xperiap
That’s weird. I’ve just tested it on my end and wpdb class was working with the get_field()
result. Maybe there’s something on your site that modifies the query. Could you please try to reproduce the issue on one of the WordPress’ stock themes (like Twenty Sixteen) with other plugins deactivated? If it disappears, then you can activate the theme and plugins one by one to see which one causes the issue.
It’s also possible that there’s something wrong with your custom table. Could you please try to get the entries from the wp_postmeta
table like this:
global $wpdb;
$varA = get_field('city');
$varB = $wpdb->get_results($wpdb->prepare(
"
SELECT *
FROM wp_postmeta
WHERE meta_value = %s
",
$varA
));
print_r( $varB );
Thanks 🙂
Thanks for the bug report.
This issue has now been fixed. Please re-download the plugin files and copy across the api/api-template.php file
or make the following code change on line 267:
} else {
$rows = $wpdb->get_results($wpdb->prepare(
"SELECT option_name, option_value FROM $wpdb->options WHERE option_name LIKE %s OR option_name LIKE %s",
$post_id . '_%' ,
'_' . $post_id . '_%'
), ARRAY_A);
if( !empty($rows) ) {
foreach( $rows as $row ) {
// vars
$name = $row['option_name'];
$prefix = $post_id . '_';
$_prefix = '_' . $prefix;
// remove prefix from name
if( strpos($name, $prefix) === 0 ) {
$name = substr($name, strlen($prefix));
} elseif( strpos($name, $_prefix) === 0 ) {
$name = '_' . substr($name, strlen($_prefix));
}
$meta[ $name ][] = $row['option_value'];
}
}
}
Cheers
E
Hi @nkals722
Thanks for the bug report.
This issue has now been fixed. Please re-download the plugin files and copy across the api/api-template.php file
or make the following code change on line 267:
} else {
$rows = $wpdb->get_results($wpdb->prepare(
"SELECT option_name, option_value FROM $wpdb->options WHERE option_name LIKE %s OR option_name LIKE %s",
$post_id . '_%' ,
'_' . $post_id . '_%'
), ARRAY_A);
if( !empty($rows) ) {
foreach( $rows as $row ) {
// vars
$name = $row['option_name'];
$prefix = $post_id . '_';
$_prefix = '_' . $prefix;
// remove prefix from name
if( strpos($name, $prefix) === 0 ) {
$name = substr($name, strlen($prefix));
} elseif( strpos($name, $_prefix) === 0 ) {
$name = '_' . substr($name, strlen($_prefix));
}
$meta[ $name ][] = $row['option_value'];
}
}
}
Cheers
E
Hi @xperiap
Could you please var_dump() the $varA
variable? Could you please try the following code?
global $wpdb;
$varA = get_field('city');
var_dump($varA);
echo "\n";
$varB = $wpdb->get_var($wpdb->prepare(
"
SELECT number
FROM database
WHERE town = %s
",
$varA
));
echo $varB;
Thanks 🙂
Hi @brandonpweb
Could you please try this code instead:
$now = new DateTime();
$date = get_field('date_time_picker', 85);
$date = new DateTime( $date );
$interval = $now->diff($date);
echo '
<div class="alert alert-info">
<button type="button" class="close" date-dismiss="alert" aria-hidden="true">&time;</button>
<strong>Time</strong><br>
Day: ' . $interval->format( '%d' ) . '<br>
Hours: ' . $interval->format( '%h' ) . '<br>
Minutes: ' . $interval->format( '%i' ) . '<br>
Seconds: ' . $interval->format( '%s' ) . '<br>
</div>
';
This page should give you more idea about it: http://stackoverflow.com/questions/14675739/php-datetime-countdown.
I hope this helps 🙂
So I modified your solution with the intent making the value optional. I’m not very good with SQL so I doubt my use of the AND
statement is the cleanest way to do that.
function acf_get_terms( $args = array() ) {
global $wpdb;
$defaults = array(
'taxonomy_slug' => '',
'acf_field_name' => null,
'meta_value' => '',
);
$args = wp_parse_args( $args, $defaults );
if ( empty($args['taxonomy_slug']) || ! taxonomy_exists( $args['taxonomy_slug'] ) || empty( $args['acf_field_name'] ) ) {
return new WP_Error( 'invalid_option_name', __('ACF term meta names are formatted as {$term->taxonomy}_{$term->term_id}_{$field[\'name\']}.') );
}
$rows = $wpdb->get_results($wpdb->prepare(
"
SELECT option_name
FROM {$wpdb->prefix}options
WHERE option_name LIKE %s
AND option_value LIKE %s
",
$args['taxonomy_slug'] . '_%_' . $args['acf_field_name'],
empty($args['meta_value']) ? '%' : $args['meta_value']
));
$unit_ids = array();
foreach( $rows as $row ){
preg_match('/^' . $args['taxonomy_slug'] . '_(\d*)_' . $args['acf_field_name'] . '$/', $row->option_name, $matches);
$unit_ids[] = $matches[1];
}
$terms = get_terms(array(
'taxonomy' => $args['taxonomy_slug'],
'hide_empty' => false,
'include' => $unit_ids,
));
return $terms;
}
ACF save the taxonomies’ value in the wp_options
table. In this case, you need to use the wpdb class.
Here’s an example how to do it:
// you can set the ID automatically. This is just an example
$location_id = 99;
// this is the taxonomy b's slug
$taxonomy_slug = 'taxonomy_b';
// this is the taxonomy b's parent field name
$taxonomy_field_name = 'location_field_name';
$rows = $wpdb->get_results($wpdb->prepare(
"
SELECT option_name
FROM {$wpdb->prefix}options
WHERE option_name LIKE %s
AND option_value = %s
",
$taxonomy_slug . '_%_' . $taxonomy_field_name,
$location_id
));
$unit_ids = array();
foreach( $rows as $row ){
preg_match('/^' . $taxonomy_slug . '_(\d*)_' . $taxonomy_field_name . '$/', $row->option_name, $matches);
$unit_ids[] = $matches[1];
}
$terms = get_terms(array(
'taxonomy' => $taxonomy_slug,
'hide_empty' => false,
'include' => $unit_ids,
));
print_r($terms);
I hope this helps 🙂
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
));
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.