I have the following code:
<?php $pages = get_pages('exclude=10'); ?>
<?php foreach ( $pages as $page ) : ?>
<?php echo $page->post_title; ?>
<?php endforeach; ?>
I would like to exclude page id 10, but I would still like to include its subpages.
However if I try to include them with the include parameter, they still don’t show up.
There are several default ways wp query to get child pages of current page. but I will prefer this. You can use WordPress get_results() function and write an SQL query like this
global $wpdb;
$child_pages = $wpdb->get_results("
SELECT * FROM {$wpdb->posts} AS p
WHERE p.post_type LIKE 'page'
AND p.post_parent LIKE 0
AND p.id NOT IN (
SELECT post_parent
FROM {$wpdb->posts} AS p
WHERE p.post_type = 'page'
AND p.post_parent != '0'
GROUP BY post_parent
)
");
Related
I've been searching through the past two days to find out where exactly could the Woocommerce products thumbnails (images) texts and URL's are stored inside the database tables, but still cannot figure this out!
I'm in a situation where I must use SQL queries to move the products data into another tables, and I have to implement the process from my phpmyadmin panel.
I already searched the wp_posts and wp_postmeta tables, wp_posts contains a guide column for the url to the product which post_type like 'product%', So far I know that in general the post stores it's thumbnalis link inside one of the posts with a type of attachment , while I need the posts with a post_type of product or like so.
Hope I can find some answers here, Thanks.
You can use the Wordpress WP_Query to get the thumbnail image of product.
$args = array(
'post_type' => 'product', //post type of product
'posts_per_page' => -1
);
$query= new WP_Query( $args );
while ( $query->have_posts() ) : $query->the_post();
global $product;
//woocommerce_get_product_thumbnail is use to get the product thumbnail link
echo '<br />' . woocommerce_get_product_thumbnail().' '.get_the_title().'';
endwhile;
wp_reset_query();
Solution 2- using the custom query as you mention in query.
//Using custom query get the details from wp_postmeta and wp_posts
//_wp_attached_file - meta key for image
$querystr = "SELECT p.*, pm2.meta_value as product_image FROM wp_posts p LEFT JOIN
wp_postmeta pm ON (
pm.post_id = p.id
AND pm.meta_value IS NOT NULL
AND pm.meta_key = '_thumbnail_id'
)
LEFT JOIN wp_postmeta pm2 ON (pm.meta_value = pm2.post_id AND pm2.meta_key = '_wp_attached_file'
AND pm2.meta_value IS NOT NULL) WHERE p.post_status='publish' AND p.post_type='product'
ORDER BY p.post_date DESC";
$upload_dir = wp_upload_dir();
//get wp_upload url
$wp_upload_url = $upload_dir['baseurl'];
$pageposts = $wpdb->get_results($querystr, OBJECT);
foreach ($pageposts as $post){
echo "<br /><a href='".$post->guid."'><img src='". $wp_upload_url.'/'.$post->product_image."'>".$post->post_title."</a>";
}
I am quite new to wordpress and blogging. I am working on a blog portal that has several blogs but they all use common categories that are listed on the main page of the website. The problem is that whichever category I choose on the main page, it shows me the page with exactly same posts.
Here is my code:
<div class="category-holder list-center">
<h5>Kategoriat</h5>
<?php $site_url = get_bloginfo( 'wpurl' ); ?>
<a target="_blank" href="<?php $site_url; ?>/tags/?avain=<?php the_field('cat1'); ?>"><?php the_field('cat1'); ?></a><br/>
<a target="_blank" href="<?php $site_url; ?>/tags/?avain=<?php the_field('cat2'); ?>"><?php the_field('cat2'); ?></a><br/>
<a target="_blank" href="<?php $site_url; ?>/tags/?avain=<?php the_field('cat3'); ?>"><?php the_field('cat3'); ?></a><br/>
<a target="_blank" href="<?php $site_url; ?>/tags/?avain=<?php the_field('cat4'); ?>"><?php the_field('cat4'); ?></a><br/>
<a target="_blank" href="<?php $site_url; ?>/tags/?avain=<?php the_field('cat5'); ?>"><?php the_field('cat5'); ?></a>
</div>
Could you please suggest some PHP function or give me any tip what I should do, where I should look for a solution for this problem?I hope that you understand that I am just a beginner and I would like to learn more about programming.
Thank you in advance!
Update: I also have a functions.php file, the part of the code that might be relevant:
function tag_posts() {
global $wpdb;
$tag = $_GET['avain'];
$taxarr = array();
$postarr = array();
$blogs = $wpdb->get_results( "SELECT blog_id FROM {$wpdb->blogs} WHERE blog_id != {$wpdb->blogid} AND site_id = '{$wpdb->siteid}' AND spam = '0' AND deleted = '0' AND archived = '0'", ARRAY_A);
array_unshift($blogs, 1);
foreach($blogs as $blog) {
$wpdb->set_blog_id($blog[ 'blog_id' ]);
$tax_id = $wpdb->get_var("SELECT term_taxonomy_id FROM $wpdb->term_taxonomy WHERE term_id IN (SELECT term_id FROM $wpdb->terms WHERE name='$tag')");
$post_id = $wpdb->get_results("SELECT object_id FROM $wpdb->term_relationships WHERE term_taxonomy_id = $tax_id");
foreach ($post_id as $id) {
$postarr = $id->object_id;
}
$posts = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}posts WHERE ID IN ($postarr)");
global $post;
foreach ($posts as $post):setup_postdata($post);
'<div class="post"><header class="post-header"><div class="date-holder"><span>'.the_time('F jS, Y').'</span></div>';
''.$post->post_title.'</header>';
'<div class="post-content">'.the_content().'</div></div>';
endforeach;
}
}
Please follow the steps. This may help you.
Create a new menu in Dashboard > Appearance > Menus.
Add categories in to the menu.
Use the function wp_nav_menu() to display the menu.
The category link in the menu displayed will direct you to the corresponding category page.
Please note that the category link direct you to the corresponding category page if and only if there exists category.php page in your themes folder.
Please, take a look at this loop here:
foreach ($post_id as $id) {
$postarr = $id->object_id;
}
$posts = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}posts WHERE ID IN ($postarr)");
It seems to be that the expected value for $postarr at the moment you query for posts is an array having post IDs. However, when you do $postarr = $id->object_id; you are overwriting the variable assigning to it only the last ID in the result set and the result is an integer variable instead of an array.
So I would suggest something like this instead:
foreach ($post_id as $id) {
$postarr[] = $id->object_id;
}
$postsAsCommaSepString = implode( ',', $postarr );
$posts = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}posts WHERE ID IN ($postsAsCommaSepString)");
First we are adding entries to the $postarr, note the brackets:
$postarr[] = $id->object_id;
Then, since we can't use an array variable as if it was a string, we need to create a string as a comma separated list of IDs to use in the SQL IN. For this, we implode the array into a string using commas as separator:
$postsAsCommaSepString = implode( ',', $postarr );
Finally, we use this new string variable in the query:
$posts = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}posts WHERE ID IN ($postsAsCommaSepString)");
This should solve the problem of fetching the same posts every time.
EDIT: Bad query:
There is also a problem in this query:
$blogs = $wpdb->get_results( "SELECT blog_id FROM {$wpdb->blogs} WHERE blog_id != {$wpdb->blogid} AND site_id = '{$wpdb->siteid}' AND spam = '0' AND deleted = '0' AND archived = '0'", ARRAY_A);
In SQL, the not equal operator goes like this <> instead of !=. Please, see the corrected form below:
$blogs = $wpdb->get_results( "SELECT blog_id FROM {$wpdb->blogs} WHERE blog_id <> {$wpdb->blogid} AND site_id = '{$wpdb->siteid}' AND spam = '0' AND deleted = '0' AND archived = '0'", ARRAY_A);
In "category.php" file I need to order my posts in this strange way:
First all the posts where author is different than "admin" (in alphabetical order by title)
Than all the post by "admin" (in the same alphabetical order)
Here is the standard code I use to do my query:
<?php global
$wp_query;
query_posts(
array_merge(
array('orderby' => 'title', 'order' => 'ASC'),
$wp_query->query
)
);
?>
Any idea about how to accomplish it without nesting two queries?
Thanks in advance!
EDIT: Following is some code that was tried, as suggested by Sepster in a previous version of his answer. But at the moment this code starts showing all the posts from 'admin' (instead of the others) until the posts with author different than 'admin' come. At that point it breaks the results and jump to the next page of results.
<?php
global $wp_query;
query_posts(
array_merge(
array('orderby' => 'title', 'order' => 'ASC'),
$wp_query->query
)
);
$adminPosts = false;
for ($i=1; $i<=2; $i++) {
while ( $wp_query->have_posts() ) {
$wp_query->the_post();
$author = get_the_author();
if ($author == 'admin' && $adminPosts == false) break;
if ($author != 'admin' && $adminPosts == true) break;
// ALL MY STUFF
} // end while
rewind_posts();
$adminPosts=true;
} // end FOR
?>
Update:
I've finally come up with a somewhat workable solution for this, but it's fair to say this really is an excercise in academics; Yes, it's do-able without executing a second loop, but really, it's pretty convoluted.
The solution is, in summary
Develop a custom SQL statement that will return the rows in the order required.
This is because in SQL, the only way to get the results in the order you need is by doing a UNION of your two subsets. To my knowledge there's no way of doing that using the "normal" WP query operations.
Execute this query, and loop over its results rather than a standard "the loop".
This is because we're getting back a recordset, rather than a WP_Query object.
Set the "Blog pages show at most X posts" setting to 1.
(on /wp-admin/options-reading.php)
A common complaint is pagination breaking when using custom queries (incidentally, the query_posts() method you're using is susceptible to this issue).
There are numerous turorials on how to do this properly, eg:
https://codex.wordpress.org/Making_Custom_Queries_using_Offset_and_Pagination
https://codex.wordpress.org/Pagination#Troubleshooting_Broken_Pagination
The first of those recommends the implementation of "Offset and Manual Pagination".
The closest I've found to an implementation of this in conjunction with a custom SQL statement is this https://wordpress.stackexchange.com/a/28717. I've borrowed heavily from this answer (and so I recommend you go over and give it an up-vote!).
However, this technique (among other more "standard" custom query approaches) suffers from a known behaviour where WP produces a 404 on the final page (if I understand correctly, because WP is still using its own query and associated max-page=posts-per-page/posts calculations to map between the page number in the URL and the delivered content).
Refer http://wordpress.org/support/topic/explanation-and-workaround-for-error-404-on-category-pagination?replies=14 for details about this issue, and a proposed solution (which unfortunately won't work for our custom SQL approach).
A known "work-around" for this issue is to reduce the number of posts-per-page to 1, as per eg http://wordpress.org/support/topic/custom-post-type-pagination-404-on-last-page
So, assuming you're happy with a global setting of 1 posts-per-page (remember you'd need to override this manually in your custom queries), here's the code:
functions.php:
...
function get_users_posts_last($userDisplayName = 'Admin', $categoryName = '') {
global $wpdb, $paged, $max_num_pages;
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$post_per_page = 5;
$offset = ($paged - 1)*$post_per_page;
$sql = "
SELECT SQL_CALC_FOUND_ROWS q.* FROM
(
(
SELECT
p.*
FROM
{$wpdb->posts} p
INNER JOIN {$wpdb->users} u ON p.post_author = u.ID
LEFT JOIN {$wpdb->term_relationships} tr ON p.ID = tr.object_id
LEFT JOIN {$wpdb->term_taxonomy} tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
LEFT JOIN {$wpdb->terms} t ON tt.term_id = t.term_id
WHERE
tt.taxonomy = 'category'
AND p.post_status = 'publish'
AND p.post_type = 'post'
AND u.display_name != '{$userDisplayName}'
" . ( $categoryName != '' ? "AND t.name = '{$categoryName}'" : "" ) . "
ORDER BY
p.post_title ASC
)
UNION
(
SELECT
p.*
FROM
{$wpdb->posts} p
INNER JOIN {$wpdb->users} u ON p.post_author = u.ID
LEFT JOIN {$wpdb->term_relationships} tr ON p.ID = tr.object_id
LEFT JOIN {$wpdb->term_taxonomy} tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
LEFT JOIN {$wpdb->terms} t ON tt.term_id = t.term_id
WHERE
tt.taxonomy = 'category'
AND p.post_status = 'publish'
AND p.post_type = 'post'
AND u.display_name = '{$userDisplayName}'
" . ( $categoryName != '' ? "AND t.name = '{$categoryName}'" : "" ) . "
ORDER BY
p.post_title ASC
)
) q
LIMIT {$offset}, {$post_per_page};
";
$sql_result = $wpdb->get_results( $sql, OBJECT);
$sql_posts_total = $wpdb->get_var( "SELECT FOUND_ROWS();" );
$max_num_pages = ceil($sql_posts_total / $post_per_page);
return $sql_result;
}
...
category.php:
...
$postList = get_users_posts_last('admin'); // Note you can also pass a category name if necessary
if($postList) {
global $post;
foreach( $postList as $key=>$post ) {
setup_postdata($post);
// Render the post here
?>
<header class='entry-header'><h1 class='entry-title'><?php the_title(); ?></h1></header>
<div class='entry-content'><?php the_content(); ?></div>
<?php
}
// Render pagination here
?>
<div class="navigation">
<div class="previous panel"><?php previous_posts_link('« Previous page',$max_num_pages) ?></div>
<div class="next panel"><?php next_posts_link('Next page »',$max_num_pages) ?></div>
</div>
<?php
}
...
Or, just set up two separate queries ;-)
the following query is used in my Wordpress blog, it gets the categories that a user has posted in. When he has a post in the category, the name of the category is shown.
It is a very very slow query because it is a big database and I have problems with the hosting company.
I have 3 categories, with id 3 called News, 4 called Articles and 5 called Others. My code is:
<?php
$author = get_query_var('author');
$categories = $wpdb->get_results("
SELECT DISTINCT(terms.term_id) as ID, terms.name, terms.slug, tax.description
FROM $wpdb->posts as posts
LEFT JOIN $wpdb->term_relationships as relationships ON posts.ID = relationships.object_ID
LEFT JOIN $wpdb->term_taxonomy as tax ON relationships.term_taxonomy_id = tax.term_taxonomy_id
LEFT JOIN $wpdb->terms as terms ON tax.term_id = terms.term_id
WHERE 1=1 AND (
posts.post_status = 'publish' AND
posts.post_author = '{$post->post_author}' AND
tax.taxonomy = 'category' )
ORDER BY terms.term_id ASC
");
?>
<ul>
<?php foreach($categories as $category) : ?>
<?php if ( ($category->ID == '3') || ($category->ID == '4') || ($category->ID == '5')) { ?>
<li>
<a href="<?php echo get_category_link( $category->ID ); ?>/?author_name=<?php echo $curuser->user_login; ?>" title="<?php echo $category->name ?>">
<?php echo $category->name; ?>
</a>
</li>
<?php } ?>
<?php endforeach; ?>
</ul>
Thank you all!
Judging by the looks of the wordpress database I have lying around, I'm guessing there is no index on the columns you are using in your WHERE clause for the wp_posts table.
Try adding an index like this:
ALTER TABLE wp_posts ADD INDEX (post_author,post_status).
I bet you see a speed up from that.
The best thing to do however is to run that query manually with an EXPLAIN in front of the SELECT, and analyze the output.
Have you indexes on posts.ID, relationships.object_ID, relationships.term_taxonomy_id, tax.term_taxonomy_id, tax.term_id, terms.term_id, posts.post_status, posts.post_author and tax.taxonomy ?
I have been presented with this code. The code displays the title headings of the latest 10 WordPress posts from the database. What I need to do is to eliminate a particular category from this. Can anyone help?
<?php require_once 'news/wp-config.php';
$howMany = 0;
$query ="SELECT `ID`, `post_title`,'post_category', `guid`,SUBSTRING_INDEX(`post_content`, ' ', 100) AS `post_excerpt` FROM $wpdb->posts WHERE `post_status`= \"publish\" AND `post_type` = \"post\" ";
$posts = $wpdb->get_results($query);
$posts = array_reverse($posts);
foreach($posts as $post)
{
if($howmany<10)
{
$link = $post->guid;
echo "<li><a target='_blank' href='$link'>$post->post_title</a></li>";
$howmany++;
}
}
?>
Or, you could use a second loop, something like this :
<div>
<h3>Fresh Posts</h3>
<ul>
<?php
$my_query = new WP_Query("cat=-3&order=DESC&posts_per_page=10");
echo "<pre>"; print_r($my_query->query_vars); echo "</pre>"; // shows the variables used to parse the query
echo "<code style='width: 175px;'>"; print_r($my_query->request); echo "</code>"; // shows the parsed query
while ($my_query->have_posts()) : $my_query->the_post(); //standard loop stuff
$do_not_duplicate[] = $post->ID;?>
<li id="post-<?php the_ID(); ?>"><?php the_title(); ?></li>
<?php endwhile; ?>
</ul>
</div>
once again WP 2.8.x. Lots of good info here : WordPress loop documentation
Determine the category you don't need and add an extra AND to your WHERE clause:
AND post_category != 3
You can do it either of 2 places. The most efficient is to do it in the query:
$query ="SELECT ID, post_title, post_category, guid, SUBSTRING_INDEX(post_content, ' ', 100) AS `post_excerpt`
FROM $wpdb->posts
WHERE post_status= 'publish'
AND post_type = 'post'
AND post_category!= 'unwanted string' ";
The other place to do it, if for some reason you need all the results, but you want to use the unwanted category somewhere else, is when you retrieve the results:
if($howmany<10 && post['post_category']!='unwanted string') {
'Noticeboard' is the name of the category i want to eliminate. but if i write that, it dispalys a parse error.
Because you must insert the category ID in the query, not the category name.
To get that, just watch in the database wp_categories table.
Some links about wordpress database:
http://blog.kapish.co.in/2008/01/18/wordpress-database-schema/
http://wpbits.wordpress.com/2007/08/08/a-look-inside-the-wordpress-database/
Anyway, I think it's more hard than this. Look at post2cat table.
So, you have to do a subquery.
I am not sure which WP version you are using, so this 'answer' has a few caveats.
Caveat 1 : This is not a complete answer, more like a pointer
Caveat 2 : The query below works with WP 2.8.x so YMMV
The query below shows how to link posts back to their categories. You can use the NOT IN mySQL operator to exclude the category you do not want by its ID
SELECT
wp_posts.*
FROM
wp_posts
INNER JOIN
wp_term_relationships
ON
(wp_posts.ID = wp_term_relationships.object_id)
INNER JOIN
wp_term_taxonomy
ON
(wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id)
WHERE
wp_term_taxonomy.taxonomy = 'category'
AND
wp_term_taxonomy.term_id NOT IN ('3')
AND
wp_posts.post_type = 'post'
AND
(wp_posts.post_status = 'publish' OR wp_posts.post_status = 'future')
GROUP BY
wp_posts.ID
ORDER BY
wp_posts.post_date
DESC
The line breaks and indenting are idiosyncratic, but (hopefully) make it easier for you to see what is going on with this query.
I hope this helps.