Combining Multiple foreach Result in json_encode - php

I am trying to get the following json_encode output:
The Array:
echo json_encode(array(
array(
'id' => 111,
'title' => "Event1",
'start' => "2012-8-10",
'end' => "2012-8-15",
'url' => "http://yahoo.com/",
),
array(
'id' => 222,
'title' => "Event2",
'start' => "2012-8-20",
'end' => "2012-8-22",
'url' => "http://yahoo.com/"
)
));
OUTPUT:
[{"id":111,"title":"Event1","start":"2012-8-10","end":"2012-8-15","url":"http:\/\/yahoo.com\/"},{"id":222,"title":"Event2","start":"2012-08-20","end":"2012-08-22","url":"http:\/\/yahoo.com\/"}]
However, when I am using the following code
global $wpdb;
$row = $wpdb->get_results("SELECT $wpdb->posts.ID, $wpdb->posts.post_title FROM $wpdb->posts WHERE $wpdb->posts.post_type = 'calendar' AND $wpdb->posts.post_status = 'publish' ORDER BY $wpdb->posts.post_date ASC");
foreach ($row as $post) {
$postid = $post->ID;
$post_title = $post->post_title;
$startDate = get_post_meta($post->ID,'calendar_start-date',true);
$endDate = get_post_meta($post->ID,'calendar_end-date',true);
$link = get_post_meta($post->ID,'calendar_link',true);
$arr = array('id' => $postid, 'title' => $post_title, 'start' => $startDate, 'end' => $endDate, 'url' => $link);
echo json_encode($arr);
}
I get the output as
{"id":"320","title":"Test Event One","start":"2012-8-17","end":"2012-8-24","url":"http:\/\/www.yahoo.com"}{"id":"321","title":"Test Event Two","start":"2012-8-21","end":"2012-8-30","url":"http:\/\/www.google.com"}
I understand it is probably due to the json_encode being inside the foreach loop. However when I try it outside, it only shows the first result. How to combine these foreach values to achieve the output as mentioned above?

you could use this:
global $wpdb;
$posts = array();
$row = $wpdb->get_results("SELECT $wpdb->posts.ID, $wpdb->posts.post_title FROM $wpdb->posts WHERE $wpdb->posts.post_type = 'calendar' AND $wpdb->posts.post_status = 'publish' ORDER BY $wpdb->posts.post_date ASC");
foreach ($row as $post) {
$postid = $post->ID;
$post_title = $post->post_title;
$startDate = get_post_meta($post->ID,'calendar_start-date',true);
$endDate = get_post_meta($post->ID,'calendar_end-date',true);
$link = get_post_meta($post->ID,'calendar_link',true);
$arr = array('id' => $postid, 'title' => $post_title, 'start' => $startDate, 'end' => $endDate, 'url' => $link);
$posts[] = $arr;
}
echo json_encode($posts);
I think that should work

Related

Wordpress Custom database table with DataTable server side processing

I have followed this toturial and have managed to create a shortcode that shows the datatable with filter option. This table works with the native post type of wordpress.
I need the same datatable but it should get the data from a custom database table i have added wp_lubuvna_subscribers
Custom Table:
So i need to change following function to get data from the above mentioned custom table instead custom post type
function datatables_server_side_callback_subscriber_db() {
header("Content-Type: application/json");
$request= $_GET;
$columns = array(
0 => 'post_title',
3 => LUBUVNA_PREFIX.'email',
1 => LUBUVNA_PREFIX.'first_name',
2 => LUBUVNA_PREFIX.'last_name',
4 => LUBUVNA_PREFIX.'phone'
);
$args = array(
'post_type' => 'lubuvna_subscriber',
'post_status' => 'publish',
'posts_per_page' => $request['length'],
'offset' => $request['start'],
'order' => $request['order'][0]['dir'],
);
if ($request['order'][0]['column'] == 0) {
$args['orderby'] = $columns[$request['order'][0]['column']];
} elseif ($request['order'][0]['column'] == 1 || $request['order'][0]['column'] == 2) {
$args['orderby'] = 'meta_value_num';
$args['meta_key'] = $columns[$request['order'][0]['column']];
}
//$request['search']['value'] <= Value from search
if( !empty($request['search']['value']) ) { // When datatables search is used
$args['meta_query'] = array(
'relation' => 'OR',
array(
'key' => 'd_title',
'value' => sanitize_text_field($request['search']['value']),
'compare' => 'LIKE'
),
array(
'key' => LUBUVNA_PREFIX.'email',
'value' => sanitize_text_field($request['search']['value']),
'compare' => 'LIKE'
),
array(
'key' => LUBUVNA_PREFIX.'first_name',
'value' => sanitize_text_field($request['search']['value']),
'compare' => 'LIKE'
),
array(
'key' => LUBUVNA_PREFIX.'last_name',
'value' => sanitize_text_field($request['search']['value']),
'compare' => 'LIKE'
),
array(
'key' => LUBUVNA_PREFIX.'phone',
'value' => sanitize_text_field($request['search']['value']),
'compare' => 'LIKE'
),
);
}
$subscriber_query = new WP_Query($args);
$totalData = $subscriber_query->found_posts;
if ( $subscriber_query->have_posts() ) {
while ( $subscriber_query->have_posts() ) {
$subscriber_query->the_post();
$nestedData = array();
$nestedData[] = get_field(LUBUVNA_PREFIX.'first_name'). '&nbsp'. get_field(LUBUVNA_PREFIX.'last_name');
$nestedData[] = "<a data-val='".get_post_field( 'post_name', get_post() )."' href='".get_permalink()."' data-posttype='".get_post_type( get_the_ID() )."' class='generallink'>" . get_field(LUBUVNA_PREFIX.'email') . "</a>";
$nestedData[] = get_field(LUBUVNA_PREFIX.'first_name');
$nestedData[] = get_field(LUBUVNA_PREFIX.'last_name');
$nestedData[] = get_field(LUBUVNA_PREFIX.'phone');
$data[] = $nestedData;
}
wp_reset_query();
$json_data = array(
"draw" => intval($request['draw']),
"recordsTotal" => intval($totalData),
"recordsFiltered" => intval($totalData),
"data" => $data
);
echo json_encode($json_data);
} else {
$json_data = array(
"data" => array()
);
echo json_encode($json_data);
}
wp_die();
}
So i will post this here, in case someone else is looking for the same solution. I had to add global $wpdband get the data from my custom database table. it works perfectly with paging / sorting / Search.
function datatables_server_side_callback_subscriber_db() {
header("Content-Type: application/json");
global $wpdb;
// Table name
$table_name = $wpdb->prefix . "lubuvna_subscribers";
// Request
$request= $_GET;
// Columns
$columns = array(
0 => 'ID',
1 => 'first_name',
2 => 'last_name',
3 => 'email',
4 => 'phone'
);
// Datatable Filters
$column = $columns[$request['order'][0]['column']];
$offset = $request['start'];
$length = $request['length'];
$order = $request['order'][0]['dir'];
// Search all columns
$sql_where = "";
if ( !empty($request['search']['value']) ) {
$sql_where .= "WHERE ";
foreach ($columns as $column) {
$sql_where .= $column . " LIKE '%" . sanitize_text_field($request['search']['value']) . "%' OR ";
}
$sql_where = substr($sql_where, 0, -3);
}
// Total Records in the datatable
$total_table_records = "SELECT count(*) as count FROM {$table_name}";
$total_fetched_records = $wpdb->get_results($total_table_records, OBJECT);
$total_records = $total_fetched_records[0]->count;
// Total Records Search
$total_table_records_search = "SELECT count(*) as count FROM $table_name $sql_where";
$total_fetched_records_search = $wpdb->get_results($total_table_records_search, OBJECT);
$total_records_search = $total_fetched_records_search[0]->count;
// Query
$total_results = $wpdb->get_results( "SELECT * FROM $table_name $sql_where ORDER BY $column $order LIMIT $offset, $length" );
if ( !empty($total_results) ) {
foreach ($total_results as $row){
$nestedData = array();
$nestedData[] = $row->ID;
$nestedData[] = $row->first_name;
$nestedData[] = $row->last_name;
$nestedData[] = $row->email;
$nestedData[] = $row->phone;
$data[] = $nestedData;
}
$json_data = array(
"draw" => intval($request['draw']),
"recordsTotal" => intval($total_records),
"recordsFiltered" => intval($total_records_search),
"data" => $data
);
echo json_encode($json_data);
} else {
$json_data = array(
"data" => array()
);
echo json_encode($json_data);
}
wp_die();
}

Associative array corresponding to column name in a table

<?php
header('Access-Control-Allow-Origin: *');
header('Content-Type: application/json');
include_once '../../config/Database.php';
include_once '../../models/Post.php';
$database = new Database();
$db = $database->connect();
$post = new Post($db);
$result = $post->read();
$num = $result->rowCount();
if ($num > 0) {
$posts_arr = array();
$posts_arr['data'] = array();
while($row = $result->fetch(PDO::FETCH_ASSOC)){
extract($row);
$post_item = array(
'id' => $id,
'title' => $title,
'body' => html_entity_decode($body),
'author' => $author,
'category_id' => $category_id,
'category_name' => $category_name
);
array_push($posts_arr['data'], $post_item);
echo json_encode($posts_arr);
}
} else {
echo json_encode(
array('message' => 'No Posts Found')
);
}
My problem :
I try to change $title to $the_title, it generates error, but when I change the column name in the table to 'the_title', it works!
My confusion is that since anything start with '$' sign is a variable, and it can be any name actually, but in this particular situation, why the name of the variable needs to be same as the name of the table's column.
$post_item = array(
'id' => $id,
'title' => $title,
'body' => html_entity_decode($body),
'author' => $author,
'category_id' => $category_id,
'category_name' => $category_name
);

Update wordpress post to draft if condition is true

I am using the below code to delete the rows from an ACF repeater field with expired date and when the number of rows reaches zero then update the post to draft mode or private mode.
But somethings are not woring (The draft thing is not working.)
$ap = get_post_meta($post->ID,'sub_seminars_0_start_date',true);
$startdate = date("Ymd", strtotime($ap));
$todaydate = date("Ymd");
if(strtotime($todaydate) > strtotime($startdate) && !empty($ap)){
$del_data = array(
'Ref' => 'sub_seminars_0_ref',
'Start date' => 'sub_seminars_0_start_date',
'End Date' => 'sub_seminars_0_end_date',
'Venue' => 'sub_seminars_0_venue',
'Fees' => 'sub_seminars_0_fees',
'CPE Credits' => 'sub_seminars_0_cpe_credits'
);
delete_row('sub_seminars', 1);
$row = count( get_field('sub_seminars') );
if ($row == 0) {
$postid = $post->ID; //Supply post-Id here $post->ID.
wp_update_post(array(
'ID' => $postid,
'post_status' => 'draft'
));
}
}
Please can anybody tell me what is wrong and how to fix it ?
$rows = get_field('sub_seminars');
$row_count = count($rows);
// $row_count = count($rows);
if ($rows == 0) {
$my_post = array(
'ID' => $post->ID,
'post_status' => 'draft'
);
wp_update_post($my_post);
}
use the above code it fixed the problem for me.

WordPress running two queries together

This is an events website that handles the location of each event relative to the users location and displays the distance in search results.
I'm using the WP GeoQuery extension to allow me to query based on distance. However, it doesn't work well with things like tax_query. So, I'm wondering if there's a way of running the WP_GeoQuery to query for events within a certain distance, then run the result of that through the normal Wp_Query to get it to filter for the correct taxonomies and other arguments?
Here's the Geo Query:
$url = "http://freegeoip.net/json/". $_SERVER['REMOTE_ADDR'] .'';
$geo = json_decode(file_get_contents($url), true);
$geo_query = new WP_GeoQuery(array(
// location stuff
'latitude' => $geo[latitude], // User's Latitude (optional)
'longitude' => $geo[longitude], // User's Longitude (optional)
// radius breaks the query if using tax_query too
'radius' => 25 // Radius to select for in miles (optional)
));
And here's the normal WP_Query:
// add query for title
function title_filter( $where, &$wp_query ) {
global $wpdb;
if ( $search_term = $wp_query->get( 'title_like' ) ) {
$where .= ' AND ' . $wpdb->posts . '.post_title LIKE \'%' . esc_sql( like_escape( $search_term ) ) . '%\'';
}
return $where;
}
add_filter( 'posts_where', 'title_filter', 10, 2 );
// dates to and from
function date_from( $from ) {
$from = str_replace("meta_key = 'date_%_start-date'", "meta_key LIKE 'date_%_start-date'", $from);
return $from;
}
add_filter('posts_where', 'date_from');
function date_to( $to ) {
$to = str_replace("mt1.meta_key = 'date_%_end-date'", "mt1.meta_key LIKE 'date_%_end-date'", $to);
return $to;
}
add_filter('posts_where', 'date_to');
// convert date to yyyymmdd
$date1 = str_replace('/', '-', $_POST['when']);
$when = date("Ymd", strtotime($date1));
$date2 = str_replace('/', '-', $_POST['when-2']);
$when2 = date("Ymd", strtotime($date2));
?>
<h1>Search</h1>
<div class="events">
<?php $args = array(
// general
'post_type' => 'event',
'post_status' => 'publish',
'posts_per_page' => 2,
'paged' => $paged,
// what input
'title_like' => $_POST['what'],
// category filter
'tax_query' => array(
array(
'taxonomy' => 'main-cat',
'field' => 'slug',
'terms' => $_POST['main-cat']
)
),
// date filter
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'date_%_start-date',
'value' => $when,
'compare' => '>=',
'type' => 'DATE'
),
array (
'key' => 'date_%_end-date',
'value' => $when2,
'compare' => '<=',
'type' => 'DATE'
)
),
);
$temp = $wp_query;
$wp_query = null;
$wp_query = new WP_Query( $args );
$wp_query->query('posts_per_page=2&post_type=event'.'&paged='.$paged);
When used individually they work fine. But I'm not sure how I can run one of them, then use the result to put through the other query. Is this even possible?

PHP/MySQL query find string in field

Ive written a query that searches for all posts that have X as a meta/custom field value.
// PSV National Query
if ($_POST['vehicleType'] == 'psv' && $_POST['coverageRegion'] == 'national' ) {
$customkey = 'vehicleType';
$customvalue = $_POST['vehicleType'];
$customkey1 = 'coverageRegion';
$customvalue1 = $_POST['coverageRegion'];
$customkey2 = 'locationType';
$customvalue2 = $_POST['locationType'];
global $wpdb;
$my_posts = $wpdb->get_results("
SELECT $wpdb->posts.*
FROM $wpdb->posts, $wpdb->postmeta, $wpdb->postmeta AS mt1
WHERE $wpdb->posts.ID = $wpdb->postmeta.post_id
AND $wpdb->postmeta.meta_key = '$customkey'
AND $wpdb->postmeta.meta_value = '$customvalue'
AND mt1.meta_key = '$customkey1'
AND mt1.meta_value = '$customvalue1'
AND mt2.meta_key = '$customkey2'
AND mt2.meta_value = '$customvalue2'
AND $wpdb->posts.post_status = 'publish'
AND $wpdb->posts.post_type = 'post'
ORDER BY $wpdb->posts.post_date DESC
");
$args = array(
'meta_query' => array(
array(
'key' => $customkey,
'value' => $customvalue,
'compare' => '='
),
array(
'key' => $customkey1,
'value' => $customvalue1,
'compare' => '='
),
array(
'key' => $customkey2,
'value' => $customvalue2,
'compare' => '='
)
)
);
$query = new WP_Query( $args );
foreach ($query as $post) :
setup_postdata($post);
echo '<div><a href="';
the_permalink();
echo '"></div>';
the_title();
endforeach;
}
Now for my post I have 1 value for each meta key and this works fine, I want to however have multiple values.
For example...
"gas, electricity, water"
When I add multiple values however the query returns null, I presumer its because im saying if...
postmeta.meta_value = '$customvalue'
Can anybody give me advice on where im going wrong?
Why don't you use the built in WP QUERY, it supports meta field array operators.
for example:
$query = new WP_Query( array(
'meta_key' => 'color',
'meta_value' => 'blue',
'meta_compare' => '!='
));
Ref: http://codex.wordpress.org/Class_Reference/WP_Query#Custom_Field_Parameters
If you are using multiple matches in a query's where clause you should use the IN variant istead of the =.
The only row I see in your query where you use $customvalue is here
AND $wpdb->postmeta.meta_value = '$customvalue'
You should change the = to IN and seperate the values with a , and quotes ' ' like this for example
AND $wpdb->postmeta.meta_value IN ('gas','electricity','water')
I ditched the $customvalue in the above code to make the point of the seperator of the IN value.
Hopefully this puts you on the right track.

Categories