array of values from acf repeater into cf7 dropdown - advanced-custom-fields

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;
}

Related

Convert datetimes from MySQL table to ISO8601 to create JSON feed in WordPress for use with FullCalendar

I've written an action in WordPress that grabs the rows from a table and encodes them in JSON format, so I can use them with the FullCalendar javascript event calendar.
The date fields from the table need to be formatted ISO8601.
In other words, when the DB renders the date/time: 2017-08-06 10:22:20, I need it converted after the query to: 2017-08-06T10:22:20 for the date fields in the query.
I'm not concerned about timezone offsets.
My function:
add_action( 'getmyevents', 'get_my_events' );
function get_my_events( $atts = [], $content = null ) {
// Use WordPress database functions
global $wpdb;
// List of events will be stored in JSON format
$json = array();
// Query retrieves list of events
$mytable = $wpdb->prefix . "my_events";
$myids = $wpdb->get_results("SELECT * FROM " . $mytable );
// sending the encoded result to success page
echo json_encode( $myids, JSON_UNESCAPED_SLASHES );
// return JSON
return $json;
}
Can someone give me a quick, direct way to convert the datetime strings in the query to ISO8601?
Maybe you can try something like this.
Although I don't know the name of your column. Uncomment the print_r to get the column name.
foreach ($myids as $key => $row) {
// print_r($row);
$date_reformatted = strtotime($row->date_col);
$myids[$key]->date_col = date( 'c', $date_reformatted );
}
It isn't the ideal answer I was looking for, but I did come up with a working solution. Mark's suggestion about filtering during the query gave me the clue I needed for it.
add_action( 'getmyevents', 'get_my_events' );
function get_my_events( $atts = [], $content = null ) {
global $wpdb;
// Values sent via ajax to calendar from my_events table
// List of events
$json = array();
// Query that retrieves events
$mytable = $wpdb->prefix . "my_events";
$myids = $wpdb->get_results( 'SELECT id, title, url, DATE_FORMAT( start, "%Y-%m-%d\T%H:%i:%s" ) as start, DATE_FORMAT( end, "%Y-%m-%d\T%H:%i:%s" ) as end, allDay FROM ' . $mytable );
// sending the encoded result to success page
echo json_encode( $myids, JSON_UNESCAPED_SLASHES );
// return JSON
return $json;
}
However, if someone else can come up with an answer that doesn't require me to specify columns by name, that would be great. Even better would be not formatting within the query at all, but rather formatting afterward. I always like to minimize processor use by MySQL as much as possible.

ACF front end form to update term

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),
);

SQL query to select products by tag in WooCommerce?

I have a WooCommerce store with products which are either tagged as a smartphone or tablet. I'm looking for a way of selecting all smartphones from the database so does anyone know the raw SQL query to select all WooCommerce products by their tag?
This will get you the results you want using a native WordPress query. Then you can traverse the results using the loop:
// Define Query Arguments
$args = array(
'post_type' => 'product',
'product_tag' => $tags
);
// Create the new query
$loop = new WP_Query( $args );
// Get products number
$product_count = $loop->post_count;
// If results
if( $product_count > 0 ) :
// Start the loop
while ( $loop->have_posts() ) : $loop->the_post(); global $product;
/** Do stuff here **/
endwhile;
else :
_e('No product matching your criteria.');
endif; // endif $product_count > 0
Credit goes to Remi Corson for this solution.

Parsing External Table Arguments in Wordpress

I have a client project that has posts assigned to their country of origin.
The client wants to be able to search the posts by continent and or region.
I have a separate table that assigns each country to its respective region, and I have the WP query that uses the resulting array:
$country_names = array('England','France','Germany',...); // this would be the result from fetching countries associated with a region.
$args = array(
'posts_per_page' => -1,
'meta_query' => array(
array(
'key' => 'country',
'value' => $country_names,
'compare' => 'IN'
)
)
);
$query = new WP_Query( $args );
What I'm having trouble with is the part in the middle. Normally, I'd use some standard PHP/MySQL to craft the array:
<?php
//Process incoming variable
if(!empty($_REQUEST['region'])){
$region = $_REQUEST['region'];
} else {
$region = NULL;
}
// Make a MySQL Connection
$query = "SELECT * FROM regions WHERE region='$region'";
$result = mysql_query($query) or die(mysql_error());
$row = mysql_fetch_array($result) or die(mysql_error());
echo $row['country'];
?>
However, I'm having trouble making it work within a WP template, since WP manages the incoming variables using its own internal functions.
Can anyone help me to connect the two together? I'm sure I'm overlooking some simple step here, or else I'm not using some built-in WP function.
Any help is appreciated.
Thanks!
ty
Add this in your functions.php
add_filter( 'query_vars', 'addnew_query_vars', 10, 1 );
function addnew_query_vars($vars)
{
$vars[] = 'region'; // region is the variable you want to add
$vars[] = 'anotherVar';
return $vars;
}
Then get it
$region=get_query_var('region')
Update
$regions = $wpdb->get_results("SELECT ".$region." FROM `".$wpdb->regions."`");
if($regions)
{
foreach($regions as $region)
{
// your code
}
}

Retrieving widget data with MySQL query in WordPress

I've built up multiple dynamic sidebars for front page item manipulation. Each sidebar contains a Text widget, and I want to retrieve each widget's content (according to widget ID) from wp_options.
Basically, the structure is dbName -> wp_options -> option_id #92 contains the following:
a:9:{i:2;a:0:{}i:3;a:3:
{s:5:"title";s:0:"";s:4:"text";s:2:"mainItem";s:6:"filter";b:0;}i:4;a:3:
{s:5:"title";s:0:"";s:4:"text";s:9:"leftThree";s:6:"filter";b:0;}i:5;a:3:
{s:5:"title";s:0:"";s:4:"text";s:10:"rightThree";s:6:"filter";b:0;}i:6;a:3:
{s:5:"title";s:0:"";s:4:"text";s:8:"rightTwo";s:6:"filter";b:0;}i:7;a:3:
{s:5:"title";s:0:"";s:4:"text";s:8:"rightOne";s:6:"filter";b:0;}i:8;a:3:
{s:5:"title";s:0:"";s:4:"text";s:7:"leftOne";s:6:"filter";b:0;}i:9;a:3:
{s:5:"title";s:0:"";s:4:"text";s:7:"leftTwo";s:6:"filter";b:0;}
s:12:"_multiwidget";i:1;}
[Actually all on one line.]
I want to retrieve the following strings:
mainItem
leftOne/leftTwo/leftThree
rightOne/rightTwo/rightThree
What's the syntax for such a query? And how can I add it to the PHP template?
You can pull all of the information about a type of widget from the database like so:
$text_widgets = get_option( 'widget_text' );
There's no need to use mySQL to get this. This will return an array of all the stored widgets of the type 'text'. Then you can loop through this array and do stuff with the internal properties of each like so:
foreach ( $text_widgets as $widget ) {
extract( $widget );
// now you have variables: $mainItem, $leftOne, $leftTwo, etc.
// do something with variables
}
Or, if you already know the ID's of the widgets you want to interact with, you can access the properties like this:
$mainItem = $text_widgets[17]['mainItem'];
Try below code snippet. It return the array of all widgets stored data.
// 1. Initialize variables
$data = '';
$all_stored_widgets = array();
// 2. Get all widgets using - `$GLOBALS['wp_widget_factory']`
$all_widgets = $GLOBALS['wp_widget_factory'];
foreach ($all_widgets->widgets as $w => $value) {
$widget_data = get_option( 'widget_' . $value->id_base );
foreach ($widget_data as $k => $v) {
if( is_numeric( $k ) ) {
$data['id'] = "{$value->id_base}-{$k}";
$data['options'] = $v;
$all_widgets_css[$value->id_base][] = $data;
}
}
}
// 3. Output:
echo '<pre>';
print_r( $all_stored_widgets );
echo '</pre>';
Output: