ACF front end form to update term - advanced-custom-fields

I want to use ACF frontend form function to create a form with custom fields
I see this issue for create new term, #Alhana
ACF front end form to create term
but I want to generate the form with old data

Well, i didn't see that question, but if it's still actual, here's a solution.
First of all, make sure you have ACF group, linked to your taxonomy. You will need ID of this group, it can be found in url on group edit page, for example:
http://site.ru/wp-admin/post.php?post=340&action=edit
In this case group ID is 340. If you don't want to use hardcoded ID (if your groups are changing from time to time), you can get it, using group name (in this example group name is Technic CPT):
global $wpdb;
$group_ID = $wpdb->get_var( "SELECT ID FROM $wpdb->posts WHERE post_title = 'Technic CPT'" );
Then, you'll need ID of term you're updating. I think, it's not nesessary to write about getting it since it's WP basics :) You'll end with something like this:
$term_id = 405;
And finally, you'll need your taxonomy's slug. In this example it's technic. So, let's render our form!
acf_form_head();
$acf_form_args = array(
'id' => 'technic_edit_form',
'post_id' => 'technic_'.$term_id,
'form' => true,
'submit_value' => 'Update technic',
'field_groups' => array($group_ID),
'updated_message' => 'Technic is updated!';
);
acf_form( $acf_form_args );
Now your term's custom fields will be shown in this form. But to save term data after editing you'll need to add some more code. ACF form assumes that you're saving post data, we'll add some logic to detect saving data for term.
add_filter( 'acf/pre_save_post', 'acf_handle_form_save', 10, 1 );
function acf_handle_form_save( $post_id ) {
// Function accepts id of object we're saving.
// All WordPress IDs are unique so we can use this to check which object it is now.
// We'll try to get term by id.
// We'll get term id with added taxonomy slug, for example 'technic_405'.
// For checking term existence we must cut out this slug.
$cut_post_id = str_replace( 'technic_', '', $post_id );
$test_tax_term = get_term_by( 'id', $cut_post_id, 'technic' );
// If $test_tax_term is true - we are saving taxonomy term.
// So let's change form behaviour to saving term instead of post.
if ( $test_tax_term ) :
// Get array of fields, attached to our taxonomy
global $wpdb;
$group_ID = $wpdb->get_var( "SELECT ID FROM $wpdb->posts WHERE post_title = 'Technic CPT'" );
$acf_fields = acf_get_fields_by_id( $group_ID );
// Then sanitize fields from $_POST
// All acf fields will be in $_POST['acf']
foreach ( $acf_fields as $acf_field ) :
$$acf_field[ 'name' ] = trim( esc_attr( strip_tags( $_POST[ 'acf' ][ $acf_field[ 'key' ] ] ) ) );
endforeach;
// We need to have some fields in our group, which are just duplicates of standard term fields: name, slug, description.
// In this example it's only one field - term name, called 'technic_name'.
$name = 'technic_name';
// Update base term info, in this example - only name.
$term = wp_update_term( $cut_post_id, 'technic', array( 'name' => $$name ) );
// If all is correct, update custom fields:
if ( !is_wp_error( $term ) ) :
foreach ( $acf_fields as $acf_field ) :
update_field( $acf_field[ 'name' ], $$acf_field[ 'name' ], 'technic_' . $cut_post_id );
endforeach;
endif;
else :
// Here is saving usual post data. Do what you need for saving it or just skip this point
endif;
return $post_id;
}
Please note: validation of $_POST data may be more complex. For example, you may have to validate array of values if there are ACF galleries or relationships among your taxonomy fields. In my example i have only common text fields.
Hope that helps!

The answer from Alhana worked for me with one change. The term object works if sent as the the value for the post_id:
$term_obj = get_term($term_id);
$acf_form_args = array(
'post_id' => $term_obj,
'post_title' => false,
'submit_value' => 'Update Term',
'field_groups' => array($group_ID),
);

Related

array of values from acf repeater into cf7 dropdown

I'm trying to populate a cf7 dropdown with values from an acf repeater. If I use a regular hardcoded array, it works just fine so somehow I'm messing up when getting the values of the repeater field.
Here's what I've got rn, trying to push the values into an array:
add_filter('wpcf7_form_tag_data_option', function($n, $options, $args) {
if (in_array('gigs', $options)){
$gigs = array();
if( have_rows('termine') ):
while ( have_rows('termine') ) : the_row();
$gigs[] = get_sub_field('termin');
endwhile;
endif;
return $gigs;
}
return $n;
}, 10, 3);
tried moving the return statement around a bit but that didn't help either and I am at a loss with my barely existing php knowledge.
Any ideas or pointers where I'm going wrong would be much appreciated.
You do have to return $n which is either null or a value which would be an array. You are close, but your returning the wrong thing. A good example of how to use this filter is by looking at the code from listo.php an you can see the correct usage of this filter.
With that said... without testing your ACF values, I can't say if your function will return those... but the below function is tested and will return data to your select with data:gigs if the ACF function works.
To retrieve the containing post's post_id you need to dig into the unit tag, and get the page id. The global $post won't work inside this filter, as it's not passing any of the loop properties to the function, so you have to specify your ACF field with the second parameter - which needs to be the parent post id.
add_filter( 'wpcf7_form_tag_data_option', 'dd_filter_form_tag_data', 10, 3 );
function dd_filter_form_tag_data( $n, $options, $args ) {
// Get the current form.
$cf7 = wpcf7_get_current_contact_form();
// Get the form unit tag.
$unit_tag = $cf7->unit_tag();
// Turn the string into an array.
$tag_array = explode( '-', $unit_tag );
// The 3rd item in the array will be the page id.
$post_id = substr( $tag_array[2], 1 );
if ( in_array( 'gigs', $options, true ) ) {
$gigs = array();
if ( have_rows( 'termine', $post_id ) ) :
while ( have_rows( 'termine', $post_id ) ) :
the_row();
$gigs[] = get_sub_field( 'termin' );
endwhile;
endif;
$n = array_merge( (array) $n, $gigs );
}
return $n;
}

Populate WordPress Advanced Custom Fields with remote JSON in backend

I have custom post types called "Products". and using the AFC(Advanced Custom Fields) plugin with this post type.
Below is what ACF has in fields group
- one filed called 'Product Description' as text area
- three text fields called 'Feature 1, Feature 2,Feature 3'
What I want to achieve is to get the data from external JSON file and populate the above ACF fields in the backend. I did some research and found Wordpress offers wp_remote_get() function to request the remote file. But I have no clue where to begin with to use this function or any other approach to use external JSON and populate these fields. Will really appreciate it someone points me to the right direction or any tutorial that shows how to achieve that. Thanks
I figured it out. View the working code below.
// Get JSON and Decode
$json_request = wp_remote_get( 'http://wp-test/test/data.json');
if( is_wp_error( $json_request ) ) {
return false;
}
$json_body = wp_remote_retrieve_body( $json_request );
$json_data = json_decode( $json_body );
// Create the new post and populate the fields
foreach( $json_data->products as $item ) {
$title = $item->title;
$desc = $item->content;
$status = $item->status;
$new_post = array(
'post_title' => $title,
'post_content' => $desc,
'post_status' => $status,
'post_author' => $userID,
'post_type' => 'products'
);
$post_id = post_exists( $title );
if (!$post_id) {
$post_id = wp_insert_post($new_post);
}
}

mysql query for category and date

How can I query the wordpress database so that I'm only display the number of posts from a certain category starting at a certain date?
I’ve tried something like this but it doesn’t work:
<?php
$user_count = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->posts WHERE term_id = '4' AND post_date >= '2014-01-01 00:00:00' " );
echo "<p>User count is {$user_count}</p>";
?>
What am I doing wrong?
Use wordpress native WP-Query:
$args = array(
'post_type' => 'post',
'date_query' => array(
'year ' => 2015,
),
'cat' => 5,
'posts_per_page'=> -1
);
$query = new WP_Query( $args );
$numberOfPosts = $query->post_count;
$numberOfPosts should hold the number you are looking for. Just paste this where you used your original code which you've shared with us.
Read more here: https://codex.wordpress.org/Class_Reference/WP_Query
Excerpt from the above mentioned url:
posts_per_page (int) - number of post to show per page (available with Version 2.1, replaced showposts parameter). Use 'posts_per_page'=>-1 to show all posts (the 'offset' parameter is ignored with a -1 value). Set the 'paged' parameter if pagination is off after using this parameter. Note: if the query is in a feed, wordpress overwrites this parameter with the stored 'posts_per_rss' option. To reimpose the limit, try using the 'post_limits' filter, or filter 'pre_option_posts_per_rss' and return -1
You can find a bunch of other options there aswell to tweak your query, to get the desired result. This should give the result you want for now.

Filtering theme_table in Drupal

I just created a data table based on a query and displayed it successfully using theme_table().
Now, I'd like to add some filters to the table but have no idea how to proceed.
Is there a built-in feature that allow me to do this easily, or should I manually add a form and update the query/redisplay the results each time the user selects something?
Thanks for your help!
I think you want to use pager_query and tablesort_sql: it's especially made for creating tables of data with pagination and sorting capabilities (and themes usually theme such tables nicely out of the box).
Example:
<?php
// The regular query without sorting or pagination parameters
$sql = 'SELECT cid, first_name, last_name, company, city FROM {clients}';
// Number of rows per page
$limit = 20;
// List of table columns ("field" is the matching database column from the sql query)
$header = array(
array('data' => t('Name'), 'field' => 'last_name', 'sort' => 'asc'),
array('data' => t('Company'), 'field' => 'company'),
array('data' => t('City'), 'field' => 'city')
);
// Calculates how to modify the SQL query according to the current pagination and sorting settings
// Then performs the database query
$tablesort = tablesort_sql($header);
$result = pager_query($sql . $tablesort, $limit);
$rows = array();
while ($client = db_fetch_object($result)) {
$rows[] = array(l($client->last_name.', '.$client->first_name, 'client/'.$client->cid), $client->company, $client->city);
}
// A message in case no results were found
if (!$rows) {
$rows[] = array(array('data' => t('No client accounts created yet.'), 'colspan' => 3));
}
// Then you can pass the data to the theme functions
$output .= theme('table', $header, $rows);
$output .= theme('pager', NULL, $limit, 0);
// And return the HTML output
print $output;
?>
(I added comments, but the original version of the example comes from this page)
Alternatively, maybe you don't need to make a module at all if you're just trying to make a page that displays a list of data, you may prefer using the Views module.

Export list of pretty permalinks and post title

Looking for a way to export a list of pretty permalinks in WordPress with the corresponding post title. Looking for the actual permalink structure defined not the shortlink. I suppose if I have to, I will use a short link, but I prefer the full permalink.
Here's a standalone PHP file you can save into the root of your website called something like /export.php and when you call it with your browser it will send a tab-delimited plain text list of posts with the pretty permalink, the post title and (as a bonus) the post type.
Just load the URL in your browser and then "save as" to a text file you can then load in Excel or however else you need to process it.
<?php
include "wp-load.php";
$posts = new WP_Query('post_type=any&posts_per_page=-1&post_status=publish');
$posts = $posts->posts;
/*
global $wpdb;
$posts = $wpdb->get_results("
SELECT ID,post_type,post_title
FROM {$wpdb->posts}
WHERE post_status<>'auto-draft' AND post_type NOT IN ('revision','nav_menu_item')
");
*/
header('Content-type:text/plain');
foreach($posts as $post) {
switch ($post->post_type) {
case 'revision':
case 'nav_menu_item':
break;
case 'page':
$permalink = get_page_link($post->ID);
break;
case 'post':
$permalink = get_permalink($post->ID);
break;
case 'attachment':
$permalink = get_attachment_link($post->ID);
break;
default:
$permalink = get_post_permalink($post->ID);
break;
}
echo "\n{$post->post_type}\t{$permalink}\t{$post->post_title}";
}
Hope this helps.
-Mike
P.S. I used the standard WordPress WP_Query() but also included a commented-out SQL in case you prefer (or need) to use it instead.
answered this one on EE this morning :)
http://wp.daveheavyindustries.com/2011/02/08/wordpress-permalink-via-sql/
this query should do it for you
SELECT wpp.post_title,
wpp.guid,
wpp.post_date,
CONCAT
(
wpo_su.option_value,
REPLACE
(
REPLACE
(
REPLACE
(
REPLACE
(
wpo.option_value,
'%year%',
date_format(wpp.post_date,'%Y')
),
'%monthnum%',
date_format(wpp.post_date, '%m')
),
'%day%',
date_format(wpp.post_date, '%d')
),
'%postname%',
wpp.post_name
)
) AS permalink
FROM wp_posts wpp
JOIN wp_options wpo
ON wpo.option_name = 'permalink_structure'
AND wpo.blog_id = 0
JOIN wp_options wpo_su
ON wpo_su.option_name = 'siteurl'
AND wpo_su.blog_id = wpo.blog_id
WHERE wpp.post_type = 'post'
AND wpp.post_status = 'publish'
ORDER BY wpp.post_date DESC
I also wanted this solution and thanks #MikeSchinkle for the original solution. I did use this to export those links in plain text to excel and then build my redirect list.
But then I found that I also wanted a solution with live, active links.
So I used the wp_query using the post type "any" and created a page template with a search form included with the following query (customize to fit your theme as you see fit). Note I had to set the posts_per_page at -1 to return unlimited results. This returns results as: "Title - Permalink"
<?php
$type = 'any';
$args = array (
'post_type' => $type,
'post_status' => 'publish',
'posts_per_page' => -1,
'order' => 'DESC',
);
$temp = $wp_query; // assign ordinal query to temp variable for later use
$wp_query = null;
$wp_query = new WP_Query($args);
if ( $wp_query->have_posts() ) :
while ( $wp_query->have_posts() ) : $wp_query->the_post();
?>
<?php the_title(); ?> - <?php the_permalink() ?><br />
<?php endwhile; ?>
<?php else :
echo '<h2>Sorry, we didnt find any results to match. Please search again below or call us at 800-828-4228 and we will be happy to help!</h2>';
get_search_form();
endif;
$wp_query = null;
$wp_query = $temp; // Reset
?>
Hope that helps others.