Wordpress/ACF merging multiple fields value to one - wordpress

Is there any way to get values from multiple fields (for example: “value_1”, “value_2”, etc.) and merge all of them to a new field, let`s say “merged_values” after publishing/editing the post?
Something like this:
If:
value_1 = red blue; value_2 = gold silver;
Then:
merged_values = red blue gold silver;
I need to achieve this, because of a search plugin, that doesn`t show the results if the search query is “red silver” and there is no option in it to combine the search within multiple ACF fields.
(to be exact, I need the “merged_values” field to be written in the db as the example above – not just echo the values together in the front-end).
The output from the default fields is pure text with spaces and the "merged_values" should also be just pure text (no arrays, etc.)

I think you want something like this
// This function runs after your post is saved
function my_acf_save_post( $post_id ) {
// Get new value of field 1
$value1 = get_field( 'field1', $post_id );
// Get new value of field 2
$value2 = get_field( 'field2', $post_id );
// Merged values with ; on the end
$merge = implode(" ",$value1).' '.implode(" ",$value2);
// Update field 3 with the new value which should be
// value1 value2;
update_field( 'field3', $merge, $post_id );
}
add_action('acf/save_post', 'my_acf_save_post', 20);
I'm not sure if you wanted to put the merged value in another ACF field. If not you can use $wpdb to insert it in de database manually.

Related

Wordpress meta query

I have created a theme with a custom post type of reports. I installed a rating plugin that interacts with this post type, allowing users to rate the reports. It stores the post rating in two fields, sum and count where sum is the total for all ratings, and count is the number of individual ratings.
Example: If a 5 people rated a post as 1, 2, 3, 4, and 5, the sum would be 15 and the count would be 5.
When a user visits the reports archive page, they see a list of all posts of the report post type. However, I want to add a query parameter to filter down to posts with an average rating of 4 or higher. I'm currently trying to use the pre_get_posts hook as follows:
add_filter( 'pre_get_posts', 'filterReports' );
function filterReports( $query ) {
if( is_post_type_archive( 'reports' ) && $_GET['top'] ) {
global $wpdb;
$query = $wpdb->prepare(
"SELECT *
FROM
wp_postmeta AS sum
wp_postmeta AS count
WHERE
sum.meta_key = 'sum' AND
count.meta_key = 'count' AND
sum.meta_value / count.meta_value >= 4"
);
}
}
I'm not entirely sure how to construct my custom query in the above. Any advice would be greatly appreciated.
Use below code will work as per your scenario.
add_filter( 'pre_get_posts', 'filterReports' );
function filterReports( $query ) {
if( is_post_type_archive( 'reports' ) && $_GET['top'] ) {
$reports_meta_query = $query->get('meta_query');
//Add our meta query to the original meta queries
$reports_meta_query[] = array(
'key'=>'count',
'value'=> 4,
'compare'=>'>=',
);
$query->set('meta_query',$reports_meta_query);
// somehow construct a query that checks if sum / count >= 4
}
}
Pretty sure the query you are looking for is something like this:
SELECT
sum.post_id,
sum.meta_value,
count.meta_value,
(sum.meta_value / count.meta_value) as result
FROM
wp_postmeta sum
LEFT JOIN wp_postmeta count USING(post_id)
WHERE
sum.meta_key = 'sum' AND
count.meta_key = 'count'
HAVING
result >= 4
You are basically joining twice the same table based on the post_id, so you can then query by the meta_key of both sum and count, then you look for the result of your math in a Having clause to check if the result would be bigger than 4 as requested.
Hope with this you can get what you were looking for.
Cheers

Count number of posts have particular meta key or value?

What I want to achieve is display the number of posts which have particular meta key or value I am getting a list of posts and meta key and value but don't know how to display them I'm storing data using repeatable fields. Storing work properly.
Now, for example, I have age meta value in two posts so how can I count no of a post with age. Age = No of post 2.
My Code :
global $wpdb;
$query = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}postmeta WHERE (meta_key = 'repeatable_fields') ");
$array = wp_json_encode($query);
print_r($array);
Outout :
[{"meta_id":"312","post_id":"108","meta_key":"repeatable_fields","meta_value":"a:2:{i:0;a:2:{s:4:\"name\";s:6:\"Zaheer\";s:5:\"phone\";s:3:\"123\";}i:1;a:2:{s:4:\"name\";s:6:\"Sageer\";s:5:\"phone\";s:11:\"09190219218\";}}"},{"meta_id":"323","post_id":"121","meta_key":"repeatable_fields","meta_value":"a:2:{i:0;a:2:{s:9:\"iif_label\";s:4:\"City\";s:11:\"iif_details\";s:7:\"karachi\";}i:1;a:2:{s:9:\"iif_label\";s:3:\"Age\";s:11:\"iif_details\";s:2:\"12\";}}"},{"meta_id":"329","post_id":"126","meta_key":"repeatable_fields","meta_value":"a:1:{i:0;a:2:{s:9:\"iif_label\";s:3:\"Age\";s:11:\"iif_details\";s:2:\"12\";}}"},{"meta_id":"332","post_id":"128","meta_key":"repeatable_fields","meta_value":"a:3:{i:0;a:2:{s:9:\"iif_label\";s:7:\"Country\";s:11:\"iif_details\";s:8:\"Pakistan\";}i:1;a:2:{s:9:\"iif_label\";s:4:\"City\";s:11:\"iif_details\";s:9:\"Islamabad\";}i:2;a:2:{s:9:\"iif_label\";s:3:\"Age\";s:11:\"iif_details\";s:2:\"12\";}}"}]
You could try something like this:
$count_age = $wpdb->get_col( $wpdb->prepare(
"
SELECT count(meta_id)
FROM {$wpdb->prefix}postmeta
WHERE meta_value LIKE '%%%s%%'
",
'Age'
));
More about get_col() here: https://codex.wordpress.org/Class_Reference/wpdb#SELECT_a_Column

Delete posts with custom field date older than current date via cronjob

I want to make a cron job witch deletes all posts older than the date in a custom field of the post. I got following function within my functions.php My custom field name is bewerbungs_frist.
function foobar_truncate_posts(){
global $wpdb;
$currenttime = new DateTime();
$currenttime_string = $currenttime->format('Ymd');
# Set your threshold of max posts and post_type name
$post_type = 'job';
# Query post type
$query = "
SELECT ID FROM $wpdb->posts
WHERE post_type = '$post_type'
AND post_status = 'publish'
ORDER BY post_modified DESC
";
$results = $wpdb->get_results($query);
# Check if there are any results
if(count($results)){
foreach($results as $post){
$customfield = get_field('bewerbungs_frist', $post->ID);
$customfield_object = new DateTime($customfield);
$customfield_string = $customfield_object->format('Ymd');
if ( $customfield_string < $currenttime_string ) {
echo "The value of the custom date field is in the past";
echo $customfield_string;
$purge = wp_delete_post($post->ID);
}
}
}
}
foobar_truncate_posts();
I use a plugin to handle my cronjobs. The Hock name is: foobar_truncate_posts and Arguments is []
The cronjob works but it does not delete those post with the date of the customfield older than todays date. The two variables are the same.
$currenttime_string 20130820
$customfield_string 20130820
there's a typo in your code, you're missing an 's' at the end of $result.
This:
foreach($result as $post){
Should be this:
foreach($results as $post){
I just tried it out. Once you make that fix the wp_delete_post() works great.
EDIT
I'm really unclear on what you're trying to do. You want to check if the custom field is set to some time in the past? What purpose does the continue serve? Also, I'm guessing you're using Advanced Custom Fields (ACF). Using the jquery Date Picker, you can format your date to Ymd by default so you don't have to convert it to a DateTime object.
At any rate, this function should explain how to properly set and compare time values, you should be able to take it from there:
function foobar_truncate_posts(){
global $wpdb;
$currenttime = new DateTime();
$currenttime_string = $currenttime->format('Ymd');
# Set your threshold of max posts and post_type name
$post_type = 'post_type_job';
# Query post type
$query = "
SELECT ID FROM $wpdb->posts
WHERE post_type = '$post_type'
AND post_status = 'publish'
ORDER BY post_modified DESC
";
$results = $wpdb->get_results($query);
# Check if there are any results
if(count($results)){
foreach($results as $post){
$customfield = get_field('bewerbungs_frist', $post->ID);
$customfield_object = new DateTime($customfield);
$customfield_string = $customfield_object->format('Ymd');
if ( $customfield_string < $currenttime_string ) {
echo "The value of the custom date field is in the past";
$purge = wp_delete_post($post->ID);
}
}
}
}
foobar_truncate_posts();

Want to create a dynamic page to list content by letter

I want to create a dynamic page in WP theme so that when I pass a letter from 'A-Z' it will display all the posts with the title starting from that letter.
Can you please tell me how to proceed?
If you are using themes and getting the index key via a query parameter then you can create a new custom theme file and add the following code to get the list of posts.
$thePostIdArray = null;
$indexkey = $_GET['indexkey'];
if ($indexkey!=null){
$querystr = "
SELECT wposts.ID
FROM $wpdb->posts wposts
WHERE UPPER(wposts.post_title) like '".$indexkey."%'
AND wposts.post_status = 'publish'
AND wposts.post_type = 'post'
ORDER BY wposts.post_title ASC
";
$thePostArray = $wpdb->get_results($querystr);
$i = 0;
foreach ($thePostArray as $currentPost){
$thePostIdArray[$i] = $currentPost->ID;
$i++;
}
After that just just a matter of going through the post array and displaying them.

Possible to convert result of Drupal db_query to PHP array?

In Drupal, I can execute a SQL as follows:
$query_object = db_query("SELECT * FROM {nodes}");
If I know the query returns only a single result (so only 1 row and 1 column), I can directly fetch it with:
$result = db_result($query_object);
If I got multiple results, I need to loop through them with something like:
$rows[] = array();
while (($row = db_fetch_object($query_object) != FALSE) {
$rows[] = $row;
}
I'm wondering if there is an easier way to do that? Is there a way that I can transfer all results into an array with a single statement? Or isn't that working, because db_result returns a cursor-like object, where you can only fetch a single row each time?
Not in Drupal 6.
In Drupal 7, there are fetch methods that can help to avoid loops like that. From http://drupal.org/node/310072:
<?php
// Retrieve all records into an indexed array of stdClass objects.
$result->fetchAll();
// Retrieve all records into an associative array keyed by the field in the result specified.
$result->fetchAllAssoc($field);
// Retrieve a 2-column result set as an associative array of field 1 => field 2.
$result->fetchAllKeyed();
// You can also specify which two fields to use by specifying the column numbers for each field
$result->fetchAllKeyed(0,2); // would be field 0 => field 2
$result->fetchAllKeyed(1,0); // would be field 1 => field 0
// Retrieve a 1-column result set as one single array.
$result->fetchCol();
// Column number can be specified otherwise defaults to first column
$result->fetchCol($column_index);
?>
In Drupal 7, you can also use:
db_query('QUERY')->fetchAll(PDO::FETCH_ASSOC);
I do always something like this ( just a simple exemple) :
$query = db_query("SELECT nid
FROM {from}
WHERE blallala
",
$tab_arg
);
if ($query->rowCount() == 0) {
$output=t('no result')
} else
{
foreach($query as $result)
{
$tab_res[]=$result;
}
foreach($tab_res as $res)
{
$output.=$res->nid;
}
}
One can also use db_fetch_array($result), where $result =db_query($queryString). As explained from the Drupal documentation:
[It returns] ...an associative array representing the next row of the result, or
FALSE. The keys of this object are the names of the table fields
selected by the query, and the values are the field values for this
result row.

Resources