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'). ' '. 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();
}
Related
I'm trying to show 4 posts from each category. Tried this code which should fetch 4 posts from respective categories. then sort them as required in col1, col2, and so on.
<?php
$col1 = $col2 = $col3 = $col4 = $col5 = array();
$parsha_terms = get_terms('parsha');
foreach($parsha_terms as $term) {
$order = get_field('parsha_order', 'term_' . $term->term_id);
$column = get_field('parsha_column', 'term_' . $term->term_id);
$color_pdf = get_field('pdf', 'term_' . $term->term_id);
$posts = get_posts(
array(
'cat' => $cat_id,
'tax_query' => array(
array(
'posts_per_page' => 4,
'taxonomy' => 'parsha',
'field' => 'term_id',
'terms' => $term->term_id,
)
)
)
);
$data = array(
'term_id' => $term->term_id,
'name' => $term->name,
'order' => $order,
'column' => $column,
'post_ids' => $posts[0]->ID,
'post_title' => $posts[0]->post_title,
'color_pdfs' => $pdfcolor,
'color_pdf_link' => $color_pdf,
);
if($column == 1) {
array_push($col1, $data);
}
else if($column == 2) {
array_push($col2, $data);
}
else if($column == 3) {
array_push($col3, $data);
}
else if($column == 4) {
array_push($col4, $data);
}
else if($column == 5) {
array_push($col5, $data);
}
}
then in output, it shows only one result(post) of each category, but it should show 4.
<?php foreach($col1 as $item) { ?>
<li>
<p><?= $item['name']; ?></p>
<?= $item['post_title']; ?>
</li>
<?php } ?>
You're retrieving an array of $posts but you're then only adding the first element $posts[0] to your $data array.
You need to loop them with foreach
$posts = get_posts(
array(
'cat' => $cat_id,
'tax_query' => array(
array(
'posts_per_page' => 4,
'taxonomy' => 'parsha',
'field' => 'term_id',
'terms' => $term->term_id,
)
)
)
);
foreach($posts as $post) {
$data = array(
'term_id' => $term->term_id,
'name' => $term->name,
'order' => $order,
'column' => $column,
'post_ids' => $post->ID,
'post_title' => $post->post_title,
'color_pdfs' => $pdfcolor,
'color_pdf_link' => $color_pdf,
);
if($column == 1) {
array_push($col1, $data);
}
else if($column == 2) {
array_push($col2, $data);
}
else if($column == 3) {
array_push($col3, $data);
}
else if($column == 4) {
array_push($col4, $data);
}
else if($column == 5) {
array_push($col5, $data);
}
}
<?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
);
I am making a plugin to display all user info in a DataTables but i am failed to implement Search, filter and Pagination . I have about 20k users. Please help me.
may be I need to change my query to join wp_users and wp_usermeta and get the result for my case. I have fount a question here and a similar tutorial here . I am not good in writing MySQL query. Please help me with this.
I get ajax response like
{
"draw": 1,
"recordsTotal": 1,
"recordsFiltered": 1,
"data": [
[
"example#mail.com",
"Some Name",
"",
"admin",
""
]
]
}
This is my table structure
<table id="user_table" class="display table table-striped table-bordered dataTable" style="width:100%">
<thead class="user-table">
<tr>
<th>Email</th>
<th>Name </th>
<th>Url</th>
<th>nickname</th>
<th>description</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
My script
jQuery(document).ready(function($){
$(window).on('load', function () {
setTimeout(loadtable, 200);
});
function loadtable(){
var ajaxurl = USERAjax.wpajaxusersearch;
var dataTable = $('#user_table').DataTable({
"processing":true,
"serverSide": true,
"order":[],
"pageLength": 10,
"ajax":{
url: ajaxurl,
type:"POST"
},
});
}
});
also added localize script like
function users_assets_scripts(){
wp_register_script( 'jquery_datatables_js', plugins_url( 'asset/js/datatables.min.js' , __FILE__ ), array(),null,true );
wp_enqueue_script( 'jquery_datatables_js' );
wp_register_style( 'jquery_datatables_css', plugins_url( 'asset/css/datatables.min.css' , __FILE__ ));
wp_enqueue_style( 'jquery_datatables_css' );
wp_localize_script( 'jquery', 'USERAjax', array('wpajaxusersearch' => admin_url( 'admin-ajax.php?action=wpajaxusersearch' )) );
}
add_action('wp_enqueue_scripts', 'users_assets_scripts');
and my data fetching function with ajax response
<?php
function wpajaxusersearch(){
$request=$_REQUEST;
global $wpdb;
$sort= "user_registered";
//Build the custom database query to fetch all user IDs
$all_users_id = $wpdb->get_results("SELECT $wpdb->users.ID FROM $wpdb->users ORDER BY $sort ASC LIMIT ".$request['start'].",".$request['length']." " );
$totalData=$wpdb->num_rows;
$data=array();
foreach ( $all_users_id as $i_users_id ) {
$user = get_userdata( $i_users_id->ID);
$email =$user->user_email;
$user_fullname =$user->first_name . ' ' . $user->last_name;
$user_url =$user->user_url;
$user_nickname =$user->nickname;
$user_profile =$user->description;
$sub_array = array();
$sub_array[] = $email;
$sub_array[] = $user_fullname;
$sub_array[] = $user_url;
$sub_array[] = $user_nickname;
$sub_array[] = $user_profile;
$data[] = $sub_array;
}
$json_data=array(
"draw" => (isset($request["draw"]) ? $request["draw"] : 0),
"recordsTotal" => intval($totalData),
"recordsFiltered" => intval($totalData),
"data" => $data
);
echo json_encode($json_data);
wp_die(); //to remove that 0 response
}
add_action( 'wp_ajax_wpajaxusersearch', 'wpajaxusersearch' );
add_action( 'wp_ajax_nopriv_wpajaxusersearch', 'wpajaxusersearch' );
Add these to your theme's 'functions.php' and everything should be fine.
// change user query to treat meta result as OR part
add_action( 'pre_user_query', 'user_meta_OR_search');
function user_meta_OR_search($q){
if ($search = $q->get('_meta_or_search')){
add_filter( 'get_meta_sql', function( $sql ) use ( $search ){
global $wpdb;
// run once
static $nr = 0;
if( 0 != $nr++ ) return $sql;
// modify WHERE
$where = sprintf(
" AND ( %s OR %s OR %s ) ",
$wpdb->prepare( "{$wpdb->users}.user_email like '%%%s%%'", $search),
$wpdb->prepare( "{$wpdb->users}.user_url like '%%%s%%'", $search),
mb_substr( $sql['where'], 5, mb_strlen( $sql['where'] ) )
);
$sql['where'] = $where;
return $sql;
});
}
}
function wpajaxusersearch()
{
$request = $_REQUEST;
$columns = array('user_email','first_name','user_url','nickname','description');
$search = esc_attr( trim( $request['search']['value'] ) );
$args = array();
$limit_args = array( 'number' => $request['length'], 'offset' => $request['start'] );
$order_args = array();
$search_args = array();
if ( isset($request['order']) && count($request['order']) )
{
$sort_column = $request['order'][0]['column'];
$sort_column_name = $columns[$sort_column];
$sort_dir = $request['order'][0]['dir'];
if( stristr( $sort_column_name,'user_' ))
$order_args = array( 'orderby' => $sort_column_name, 'order' => $sort_dir );
else
$order_args = array( 'meta_key' => $sort_column_name, 'orderby' => 'meta_value', 'order' => $sort_dir );
}
else
$order_args = array( 'orderby' => 'user_registered', 'order' => 'ASC' );
$args = $order_args;
if(isset($search) && $search != "")
{
$search_args = array(
'_meta_or_search' => "*{$search}*",
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'first_name',
'value' => $search,
'compare' => 'LIKE'
),
array(
'key' => 'last_name',
'value' => $search,
'compare' => 'LIKE'
),
array(
'key' => 'nickname',
'value' => $search,
'compare' => 'LIKE'
),
array(
'key' => 'description',
'value' => $search,
'compare' => 'LIKE'
)
)
);
}
$all_users = new WP_User_Query( $args );
$total_users = count($all_users->get_results());
$filtered_users = count($all_users->get_results());
if(isset($search) && $search != "")
{
$args = array_merge($args, $search_args);
$all_users = new WP_User_Query( $args );
$filtered_users = count($all_users->get_results());
}
$args = array_merge($args, $limit_args);
$all_users = new WP_User_Query( $args );
foreach ( $all_users->get_results() as $user ) {
$email = $user->user_email;
$user_fullname = $user->first_name . ' ' . $user->last_name;
$user_url = $user->user_url;
$user_nickname = $user->nickname;
$user_profile = $user->description;
$sub_data = array();
$sub_data[] = $email;
$sub_data[] = $user_fullname;
$sub_data[] = $user_url;
$sub_data[] = $user_nickname;
$sub_data[] = $user_profile;
$data[] = $sub_data;
}
$json_data=array(
"draw" => (isset($request["draw"]) ? $request["draw"] : 0),
"recordsTotal" => intval($total_users),
"recordsFiltered" => intval($filtered_users),
"data" => $data
);
echo json_encode($json_data);
wp_die();
}
add_action( 'wp_ajax_wpajaxusersearch', 'wpajaxusersearch' );
add_action( 'wp_ajax_nopriv_wpajaxusersearch', 'wpajaxusersearch' );
I am building a ajax search that uses wp_query and I need to be able to filter using custom meta and custom taxonomy names. I've gotten the custom meta part working but cannot get it to filter using the taxonomy names. What I've got so far -
$useCustomJoins = false;
add_action( 'pre_get_posts', function( $q )
{
if( $title = $q->get( '_meta_or_title' ) )
{
add_filter( 'get_meta_sql', function( $sql ) use ( $title )
{
global $wpdb;
// Only run once:
static $nr = 0;
if( 0 != $nr++ ) return $sql;
// Modified WHERE
$sql['where'] = sprintf(
" AND ( %s OR %s ) ",
$wpdb->prepare( "{$wpdb->posts}.post_title like '%%%s%%'", $title),
mb_substr( $sql['where'], 5, mb_strlen( $sql['where'] ) )
);
return $sql;
});
}
});
add_filter('posts_join', array('CrownResources', 'filterPostsJoin'), 10, 2);
add_filter('posts_where', array('CrownResources', 'filterPostsWhere'), 10, 2);
add_filter('posts_groupby', array('CrownResources', 'filterPostsGroupby'), 10, 2);
public static function filterPostsJoin($join, $query) {
global $wpdb, $useCustomJoins;
if($useCustomJoins || (is_main_query() && is_search())) {
$join .= "
LEFT JOIN
(
{$wpdb->term_relationships}
INNER JOIN
{$wpdb->term_taxonomy} ON {$wpdb->term_taxonomy}.term_taxonomy_id = {$wpdb->term_relationships}.term_taxonomy_id
INNER JOIN
{$wpdb->terms} ON {$wpdb->terms}.term_id = {$wpdb->term_taxonomy}.term_id
)
ON {$wpdb->posts}.ID = {$wpdb->term_relationships}.object_id ";
}
return $join;
}
public static function filterPostsWhere($where, $query) {
global $wpdb, $useCustomJoins;
if($useCustomJoins || (is_main_query() && is_search())) {
$userWhere = self::getUserPostsWhere();
$queryS = !empty(get_query_var('s')) ? get_query_var('s') : get_query_var('_meta_or_title');
$where .= " OR (
{$wpdb->term_taxonomy}.taxonomy IN('resource_pregnancy_taxonomy', 'resource_counseling_taxonomy', 'resource_classes_taxonomy', 'resource_supplies_taxonomy', 'resource_clothing_taxonomy', 'resource_food_taxonomy', 'resource_housing_taxonomy', 'resource_medical_taxonomy', 'resource_substance_taxonomy', 'adoption_taxonomy', 'employment_taxonomy')
AND
{$wpdb->terms}.name LIKE '%".esc_sql($queryS)."%'
{$userWhere}
)";
}
return $where;
}
protected static function getUserPostsWhere() {
global $wpdb;
$userId = get_current_user_id();
$sql = '';
$status = array("'publish'");
if(0 !== $userId) {
$status[] = "'private'";
$sql .= " AND {$wpdb->posts}.post_author = ".absint($userId);
}
$sql .= " AND {$wpdb->posts}.post_status IN( ".implode(',', $status)." ) ";
return $sql;
}
public static function filterPostsGroupby($groupby, $query) {
global $wpdb, $useCustomJoins;
if($useCustomJoins || (is_main_query() && is_search())) {
$groupby = "{$wpdb->posts}.ID";
}
return $groupby;
}
usage:
global $post, $useCustomJoins;
$original_post = $post;
// query for resource
$queryArgs = array(
'post_type' => 'resource',
'posts_per_page' => -1,
'orderby' => 'menu_order',
'order' => 'ASC',
'post_status' => 'publish'
);
//if taxonomies
if (!empty($atts['taxonomies'])){
$queryArgs['tax_query'] = array();
foreach ($atts['taxonomies'] as $tax){
$queryArgs['tax_query'][] = array(
'taxonomy' => $tax['name'],
'field' => 'term_id',
'terms' => $tax['terms'],
'operator' => 'AND',
);
}
}
// filter by meta as well as title
$meta_query = array();
$meta_query[] = array(
'key' => 'resource_description',
'value' => $atts['search'],
'compare' => 'LIKE'
);
$meta_query[] = array(
'key' => 'resource_address',
'value' => $atts['search'],
'compare' => 'LIKE'
);
$meta_query[] = array(
'key' => 'resource_date_time',
'value' => $atts['search'],
'compare' => 'LIKE'
);
$meta_query[] = array(
'key' => 'resource_phone',
'value' => $atts['search'],
'compare' => 'LIKE'
);
$meta_query[] = array(
'key' => 'resource_email',
'value' => $atts['search'],
'compare' => 'LIKE'
);
$meta_query[] = array(
'key' => 'resource_website',
'value' => $atts['search'],
'compare' => 'LIKE'
);
//if there is more than one meta query 'or' then
if(count($meta_query) > 1) {
$meta_query['relation'] = 'OR';
}
//if there's a search
if (!empty($atts['search'])){
// $queryArgs['s'] = $atts['search'];
$queryArgs['_meta_or_title'] = $atts['search']; //not using 's' anymore
$queryArgs['meta_query'] = $meta_query;
$useCustomJoins = true;
}
$resourceQuery = new \WP_Query($queryArgs);
$useCustomJoins = false;
Any idea on how to get them working together? I can get the meta filter to search properly but once I add the taxonomy it still filters but not correctly.
I have a form that allows a user to select a county from a dropdown menu, My form is then posted to my functions.php page where I've been using IF statements to run my queries.
if ($_POST['dropdown1'] == 'option 1' && $_POST['dropdown 2'] == 'option 4' && $_POST['county'] == 'cheshire' ) {
// RUN QUERY
}
My problem is however I can't realistically use IF statements for every county in every possible scenario as there will be thousands of options, has anybody got a better idea of how I can do this?
if ($_POST['vehicleType'] == 'hgv' && $_POST['coverageRegion'] == 'national' ) {
$customkey = 'vehicleType';
$customvalue = $_POST['vehicleType'];
$customkey1 = 'coverageRegion';
$customvalue1 = $_POST['coverageRegion'];
$customkey2 = 'locationType';
$customvalue2 = $_POST['locationType']; $args = array('orderby' => 'meta_value_num', 'meta_key' => 'order', 'order' => 'ASC',
'meta_query' => array(
array(
'key' => $customkey,
'value' => $customvalue,
'compare' => '='
),
array(
'key' => $customkey1,
'value' => $customvalue1,
'compare' => '='
),
array(
'key' => $customkey2,
'value' => $customvalue2,
'compare' => '='
)
) // end of array
); //end of if
$query = new WP_Query( $args);
// The Loop
$i = 0; $i = -1;
while ( $query->have_posts() )
{
$i++;
$query->the_post();
if ( $keys = get_post_custom_keys() )
{
echo "<div class='clearfix card-prod ".($i==0?'first':'')."'><div class='top-dets'><span class='card-title'>";
echo the_title();
echo "</span>";
// Network query
$network_value = get_post_custom_values('srchnetwork');
foreach ( $network_value as $key => $value ) {
echo '<span class="srch-val-">'. $value . '</span>'; }// Pricing Query
$pricing_value = get_post_custom_values('srchpricing');
foreach ( $pricing_value as $key => $value ) {
echo '<span class="srch-val-1">'. $value . '</span>'; }
// Setup Query
$setup_value = get_post_custom_values('srchsetupfee');
foreach ( $setup_value as $key => $value ) {
echo '<span class="srch-val-2">'. $value . '</span>'; }
// Services Query
$services_value = get_post_custom_values('srchservices');
foreach ( $services_value as $key => $value ) {
echo '<span class="srch-val-3">'. $value . '</span></div>'; }
// Big Card Query
$bigcard_value = get_post_custom_values('bigcard');
foreach ( $bigcard_value as $key => $value ) {
echo '<a href="/" class="cardclick"><img src="/wp-content/themes/CAFC/images/cards/'. $value . '" alt="'; }
echo the_title() . '" /></a>';
echo '<img src="wp-content/themes/CAFC/images/top-choice.jpg" alt="Top Choice" class="topchoice">';
echo the_excerpt()."</div>"; }
}
}
You can write your code in this way so you don't have to deal with every possible option.
global $wpdb;
$postKeys = array('vehicleType', 'coverageRegion', 'locationType');
$args = array(
'orderby' => 'meta_value_num',
'meta_key' => 'order',
'order' => 'ASC',
'meta_query' => array()
);
foreach ($postKeys as $key) {
$args['meta_query'][] = array(
'key' => $key,
'value' => $wpdb->escape($_POST[$key]),
'compare' => '='
);
}
$query = new WP_Query($args);