Wordpress : wpdb prepare with conditional - php

I'm trying to use sql->prepare with many strings concatenation.
In my code below, I try to call a function which will return me an array of get_post from $wpdb->prepare.
function test($array){
$sqlprep = "SELECT SQL_CALC_FOUND_ROWS p.ID
FROM {$wpdb->prefix}posts p
LEFT JOIN {$wpdb->prefix}postmeta m ON m.post_id = p.ID
LEFT JOIN {$wpdb->prefix}term_relationships r ON (p.ID = r.object_id)
LEFT JOIN {$wpdb->prefix}term_relationships r1 ON (p.ID = r1.object_id)
LEFT JOIN {$wpdb->prefix}term_relationships r2 ON (p.ID = r2.object_id)
LEFT JOIN {$wpdb->prefix}term_taxonomy tt ON tt.term_taxonomy_id = r.term_taxonomy_id
LEFT JOIN {$wpdb->prefix}terms t ON t.term_id = tt.term_id AND t.term_id = r.term_taxonomy_id
WHERE 1=1";
if(isset($array['post_type']) && !empty($array['post_type']){
$sqlprep .= " AND p.post_type = '".$array['post_type']."'";
}
if(isset($array['post_type']) && !empty($array['post_type']){
$sqlprep .= " AND p.post_type = '".$array['post_status']."'";
}
$sql = $wpdb->prepare($sqlprep);
$ids = $wpdb->get_col($sql);
return array_map('get_post', $ids)
}
and the value is an array which is :
$args=array(
'post_type' => 'post',
'post_status' => 'published',
);
When I try to print_r($sql) to get the query, it always just stop till WHERE 1=1.
Can string concatenation be used for wpdb prepare?

Pay attention to the use of the properties in the $wpdb object and the use of the prepare method, furthermore there is an issue with the column name for the post_status:
function test($array){
$sql = "SELECT SQL_CALC_FOUND_ROWS p.ID
FROM {$wpdb->posts} p
LEFT JOIN {$wpdb->postmeta} m ON m.post_id = p.ID
LEFT JOIN {$wpdb->term_relationships} r ON (p.ID = r.object_id)
LEFT JOIN {$wpdb->term_relationships} r1 ON (p.ID = r1.object_id)
LEFT JOIN {$wpdb->term_relationships} r2 ON (p.ID = r2.object_id)
LEFT JOIN {$wpdb->term_taxonomy} tt ON tt.term_taxonomy_id = r.term_taxonomy_id
LEFT JOIN {$wpdb->terms} t ON t.term_id = tt.term_id AND t.term_id = r.term_taxonomy_id
WHERE 1=1";
if(isset($array['post_type']) && !empty($array['post_type']){
$sql .= $wpdb->prepare(" AND p.post_type = %s", $array['post_type']);
}
if(isset($array['post_type']) && !empty($array['post_type']){
$sql .= $wpdb->prepare(" AND p.post_status = %s", $array['post_status']);
}
$ids = $wpdb->get_col($sql);
return array_map('get_post', $ids)
}

Related

Get products with specific attribute term and specific category term in Woocommerce using SQL

I wish to find products with two different criteria.
The code I used first to search one criteria is;
SELECT rel.object_id, rel.term_taxonomy_id, tt.taxonomy, tt.term_id, ts.name
FROM df1wrmw_term_taxonomy tt
INNER JOIN df1wrmw_term_relationships rel ON tt.term_taxonomy_id = rel.term_taxonomy_id
INNER JOIN df1wrmw_terms ts ON tt.term_id = ts.term_id
WHERE tt.taxonomy = "pa_1_scale"
AND ts.term_id = 400;
This returns all those products (Object_ID) with the attribute "pa_1_scale" and ts.term_id = 400. I can also do this to return all products with product_cat and ts.term_id = 397, using a different WHERE statement
WHERE tt.taxonomy = "product_cat"
AND ts.term_id = 397
UNION ALL just combines the two. How do I get SQL to select both these criteria? I know a WHERE statement combining the two criteria will not work as I think that no table row contains both values?
Any help available would be great.
You can try to use the following that will join duplicated tables with a different variable reference, allowing to combine both queries in one:
SELECT tr.object_id, tr.term_taxonomy_id, tt.taxonomy, t.term_id, t.name,
tr2.term_taxonomy_id as term_taxonomy_id2, tt2.taxonomy as taxonomy2,
t2.term_id as term_id2, t2.name as name2
FROM df1wrmw_term_relationships tr
INNER JOIN df1wrmw_term_taxonomy tt
ON tr.term_taxonomy_id = tt.term_taxonomy_id
INNER JOIN df1wrmw_terms t
ON tt.term_id = t.term_id
INNER JOIN df1wrmw_term_relationships tr2
ON tr.object_id = tr2.object_id
INNER JOIN df1wrmw_term_taxonomy tt2
ON tr2.term_taxonomy_id = tt2.term_taxonomy_id
INNER JOIN df1wrmw_terms t2
ON tt2.term_id = t2.term_id
WHERE tt.taxonomy = 'pa_1_scale'
AND t.term_id = 400
AND tt2.taxonomy = 'product_cat'
AND t2.term_id = 397
Or you can use in WordPress the class WPDB and its methods to get SQL query results in PHP:
global $wpdb;
$results = $wpdb->get_results("
SELECT tr.object_id, tr.term_taxonomy_id, tt.taxonomy, t.term_id, t.name,
tr2.term_taxonomy_id as term_taxonomy_id2, tt2.taxonomy as taxonomy2,
t2.term_id as term_id2, t2.name as name2
FROM {$wpdb->prefix}term_relationships tr
INNER JOIN {$wpdb->prefix}term_taxonomy tt
ON tr.term_taxonomy_id = tt.term_taxonomy_id
INNER JOIN {$wpdb->prefix}terms t
ON tt.term_id = t.term_id
INNER JOIN {$wpdb->prefix}term_relationships tr2
ON tr.object_id = tr2.object_id
INNER JOIN {$wpdb->prefix}term_taxonomy tt2
ON tr2.term_taxonomy_id = tt2.term_taxonomy_id
INNER JOIN {$wpdb->prefix}terms t2
ON tt2.term_id = t2.term_id
WHERE tt.taxonomy = 'pa_1_scale'
AND t.term_id = 400
AND tt2.taxonomy = 'product_cat'
AND t2.term_id = 397
");
// Display preformatted raw output
echo '<pre>' . print_pr($results, true) . '</pre>';
It should work.

Optimise Custom Wordpress SQL query

I have a wordpress website whereby I am doing an ajax request to return a json object of property details (to use with google maps). I currently have the following query:
SELECT
p.ID AS 'id',
p.post_title AS 'title',
t.name AS 'property_type',
c.name AS 'listing_type',
pm.meta_value AS 'address',
pm2.meta_value AS 'latitude',
pm3.meta_value AS 'longitude',
pm4.meta_value AS 'price',
pm5.meta_value AS 'bedrooms',
pm6.meta_value AS 'baths',
pm7.meta_value AS 'show_date',
p.guid,
wm2.meta_value AS 'image'
FROM
wp_posts p
INNER JOIN
wp_postmeta AS pm ON pm.post_id = p.ID
INNER JOIN
wp_postmeta AS pm2 ON pm2.post_id = p.ID
INNER JOIN
wp_postmeta AS pm3 ON pm3.post_id = p.ID
INNER JOIN
wp_postmeta AS pm4 ON pm4.post_id = p.ID
INNER JOIN
wp_postmeta AS pm5 ON pm5.post_id = p.ID
INNER JOIN
wp_postmeta AS pm6 ON pm6.post_id = p.ID
INNER JOIN
wp_postmeta AS pm7 ON pm7.post_id = p.ID
LEFT JOIN
wp_term_relationships AS r ON (p.ID = r.object_id)
INNER JOIN
wp_term_taxonomy AS x ON (r.term_taxonomy_id = x.term_taxonomy_id)
INNER JOIN
wp_terms AS t ON (r.term_taxonomy_id = t.term_id)
LEFT JOIN
wp_term_relationships AS v ON (p.ID = v.object_id)
INNER JOIN
wp_term_taxonomy AS z ON (v.term_taxonomy_id = z.term_taxonomy_id)
INNER JOIN
wp_terms AS c ON (v.term_taxonomy_id = c.term_id)
LEFT JOIN
wp_postmeta wm1 ON (wm1.post_id = p.id
AND wm1.meta_value IS NOT NULL
AND wm1.meta_key = '_thumbnail_id')
LEFT JOIN
wp_postmeta wm2 ON (wm1.meta_value = wm2.post_id
AND wm2.meta_key = '_wp_attached_file'
AND wm2.meta_value IS NOT NULL)
WHERE
pm.meta_key = 'property_address'
AND pm2.meta_key = 'property_lat'
AND pm3.meta_key = 'property_lng'
AND pm4.meta_key = 'property_price'
AND pm5.meta_key = 'property_beds'
AND pm6.meta_key = 'property_baths'
AND pm7.meta_key = 'property_show_date'
AND x.taxonomy = 'property-type'
AND z.taxonomy = 'listing-type'
AND p.post_type = 'property'
AND p.post_status = 'publish'
which returns the data perfectly:
id | title | property_type | listing_type | address | latitude | longitude | price | bedrooms | baths | show_date | guid
however, as soon as I have more than one property on the website the query seems to struggle and even breaks the database (Completely lost the ability to connect to db taking the website down, having to start again with a new db). I have pinned the problem down to the taxonomy part of my query:
LEFT JOIN
wp_term_relationships AS r ON (p.ID = r.object_id)
INNER JOIN
wp_term_taxonomy AS x ON (r.term_taxonomy_id = x.term_taxonomy_id)
INNER JOIN
wp_terms AS t ON (r.term_taxonomy_id = t.term_id)
LEFT JOIN
wp_term_relationships AS v ON (p.ID = v.object_id)
INNER JOIN
wp_term_taxonomy AS z ON (v.term_taxonomy_id = z.term_taxonomy_id)
INNER JOIN
wp_terms AS c ON (v.term_taxonomy_id = c.term_id)
but I have no idea how to improve on this.
Does anyone have any ideas?
$query = "SELECT DISTINCT
id,
post_title,
guid,
pm.meta_value AS 'address',
pm2.meta_value AS 'latitude',
pm3.meta_value AS 'longitude',
pm4.meta_value AS 'price',
pm5.meta_value AS 'bedrooms',
pm6.meta_value AS 'baths',
pm7.meta_value AS 'show_date',
wm2.meta_value AS 'image',
(SELECT
GROUP_CONCAT(wp_terms.name
SEPARATOR ', ')
FROM
wp_terms
INNER JOIN
wp_term_taxonomy ON wp_terms.term_id = wp_term_taxonomy.term_id
INNER JOIN
wp_term_relationships wpr ON wpr.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id
WHERE
taxonomy = 'property-type'
AND wp_posts.ID = wpr.object_id) AS 'property_type',
(SELECT
GROUP_CONCAT(wp_terms.name
SEPARATOR ', ')
FROM
wp_terms
INNER JOIN
wp_term_taxonomy ON wp_terms.term_id = wp_term_taxonomy.term_id
INNER JOIN
wp_term_relationships wpr ON wpr.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id
WHERE
taxonomy = 'listing-type'
AND wp_posts.ID = wpr.object_id) AS 'listing_type'
FROM
wp_posts
INNER JOIN
wp_postmeta AS pm ON pm.post_id = wp_posts.ID
INNER JOIN
wp_postmeta AS pm2 ON pm2.post_id = wp_posts.ID
INNER JOIN
wp_postmeta AS pm3 ON pm3.post_id = wp_posts.ID
INNER JOIN
wp_postmeta AS pm4 ON pm4.post_id = wp_posts.ID
INNER JOIN
wp_postmeta AS pm5 ON pm5.post_id = wp_posts.ID
INNER JOIN
wp_postmeta AS pm6 ON pm6.post_id = wp_posts.ID
INNER JOIN
wp_postmeta AS pm7 ON pm7.post_id = wp_posts.ID
INNER JOIN
wp_postmeta wm1 ON (wm1.post_id = wp_posts.id
AND wm1.meta_value IS NOT NULL
AND wm1.meta_key = '_thumbnail_id')
INNER JOIN
wp_postmeta wm2 ON (wm1.meta_value = wm2.post_id
AND wm2.meta_key = '_wp_attached_file'
AND wm2.meta_value IS NOT NULL)
WHERE
post_type = 'property'
AND pm.meta_key = 'property_address'
AND pm2.meta_key = 'property_lat'
AND pm3.meta_key = 'property_lng'
AND pm4.meta_key = 'property_price'
AND pm5.meta_key = 'property_beds'
AND pm6.meta_key = 'property_baths'
AND pm7.meta_key = 'property_show_date'";

Run a script for a SQL query [select from where] on php

I need to run some SQL queries that I gotten them from a wp database in arrays forms.
For example I have this SQL query:
SELECT *
FROM wp_posts p
LEFT OUTER JOIN wp_term_relationships r ON r.object_id = p.ID
LEFT OUTER JOIN wp_terms t ON t.term_id = r.term_taxonomy_id
WHERE p.ID in ('800', '808', '569')
AND p.post_type = 'post'
AND p.post_status = 'publish'
How do I execute it in PHP?
So far I have created a new mysqli connection and connected it to the wordpress database I have. How do I run from there?
I was thinking to use the mysqli::query function but how to put it in action? I would really appreciate it if someone could help me.
Cheers
You do not need to create a separate MySQL connection within WordPress,
WordPress already did it you can simply call the $wpdb global object and you can use them
For example
global $wpdb;
$results = $wpdb->get_results("SELECT * FROM wp_posts p LEFT OUTER JOIN wp_term_relationships r ON r.object_id = p.ID LEFT OUTER JOIN wp_terms t ON t.term_id = r.term_taxonomy_id WHERE p.ID in ('800','808', '569') AND p.post_type = 'post' AND p.post_status = 'publish' ");
More info
https://codex.wordpress.org/Class_Reference/wpdb
You can try this. I hope it works.
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "SELECT *
FROM wp_posts p
LEFT OUTER JOIN wp_term_relationships r ON r.object_id = p.ID
LEFT OUTER JOIN wp_terms t ON t.term_id = r.term_taxonomy_id
WHERE p.ID in ('800','808', '569')
AND p.post_type = 'post'
AND p.post_status = 'publish' ";
$result = $conn->query($sql);
for me, with the help of #Faisal Shahzad it worked like this
<?php
$conn = mysqli_connect("localhost","root","password","db_db");
mysqli_set_charset($conn,"utf8");
// Check connection
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
// three specific posts
$q1 = "SELECT post_title, post_content, guid
FROM wp_posts p
#LEFT OUTER JOIN wp_postmeta pm ON p.ID = pm.post_id AND pm.meta_key = '_thumbnail_id'
LEFT OUTER JOIN wp_term_relationships r ON r.object_id = p.ID
LEFT OUTER JOIN wp_terms t ON t.term_id = r.term_taxonomy_id
WHERE p.ID in ('800','808', '569')
AND p.post_type = 'post'
AND p.post_status = 'publish'";
if ($result = $conn->query($q1))
{
while ($row = $result->fetch_assoc())
{
// SHOW three specific posts
#printf("Title: %s\r\n",$row['_thumbnail_id']); echo "<br><hr>";
printf("Title: %s\r\n",$row['post_title']); echo "<br><hr>";
printf("Content: %s\r\n",$row['post_content']); echo "<br><hr>";
printf("Link: %s\r\n",$row['guid']); echo "<br><hr>";
}}
?>

how can select all post relevant to category in wordpress?

How can select all posts related to one category in wordpress by mysql query and echo by json format ?
I hope this MySQL will serve your purpose.
SELECT *
FROM wp_posts p
LEFT OUTER JOIN wp_term_relationships r ON r.object_id = p.ID
LEFT OUTER JOIN wp_terms t ON t.term_id = r.term_taxonomy_id
WHERE p.post_status = 'publish'
AND p.post_type = 'post'
AND t.slug = 'your_category_slug'
Just replace your_category_slug with your category slug, of which category post u want.
I hope the following code will help you to get data posts from specific category.
<?php
global $wpdb;
$query = "SELECT *
FROM wp_posts p
LEFT OUTER JOIN wp_term_relationships r ON r.object_id = p.ID
LEFT OUTER JOIN wp_terms t ON t.term_id = r.term_taxonomy_id
WHERE p.post_status = 'publish'
AND p.post_type = 'post'
AND t.slug = 'your_category_slug'";
$results = $wpdb->get_results( $query, OBJECT );
?>

sql statement for querying wp posts from specific category

i want to query wordpress posts from specific category parent but the problem is that there is no such column on wp_posts table so i need to join but my skills on the sql is not good so i need some help ,
here is the query i use for querying posts
$query = "SELECT c.*
FROM {$wpdb->prefix}posts p,
{$wpdb->prefix}comments c WHERE p.ID = c.comment_post_ID AND c.comment_approved > 0 AND p.post_type = 'product' AND p.post_status = 'publish' AND
p.comment_count > 0 ORDER BY ".$order_by." LIMIT 0, ". $number_of_comments;
}
and here is some snippet i found for joining term_taxonomy_id
$answer = $wpdb->get_results("SELECT post_title, post_content, term_taxonomy_id FROM wp_posts LEFT JOIN wp_term_relationships ON wp_posts.ID = wp_term_relationships.object_id WHERE SUBSTRING(post_title,1,1)='T' AND term_taxonomy_id=6");
the proplem i can't seem to figure how to use this example on my query neither thinking of simpler solutions so i can query from specific parent category , thanks for your help
here is the query i used and worked ..
$query = "SELECT c.*
FROM
{$wpdb->prefix}comments c ,
{$wpdb->prefix}posts p JOIN $wpdb->term_relationships TR
ON p.ID=TR.object_id
JOIN $wpdb->term_taxonomy T
ON TR.term_taxonomy_id=T.term_taxonomy_id
JOIN $wpdb->terms TS
ON T.term_id = TS.term_id
WHERE p.ID = c.comment_post_ID AND c.comment_approved > 0 AND p.post_type = 'product' AND p.post_status = 'publish' AND
p.comment_count > 0 AND T.taxonomy = 'product_cat' AND T.term_id='$term_cat' ORDER BY ".$order_by." LIMIT 0, ". $number_of_comments;
}
you would be looking at something like this:
global $wpdb;
$wpdb->show_errors();
$ur=$wpdb->get_results( $wpdb->prepare(
"
SELECT *
FROM $wpdb->posts P
JOIN $wpdb->term_relationships TR
ON P.ID=TR.object_id // identify link column
JOIN $wpdb->term_taxonomy T
ON TR.term_taxonomy_id=T.term_taxonomy_id
JOIN $wpdb->terms TS
ON T.term_id = TS.term_id
WHERE P.post_type = %d // use wild chars (define below, this one equals carmarket)
AND P.post_status = %f
AND T.taxonomy= %s
",
'carmarket',
'publish',
'carmake'
) );
$wpdb->print_error();
var_dump($ur);

Categories